- Русские Блоги
- Введение в процесс разработки Android JNI
- 1. Что такое JNI
- 2. Что такое NDK
- 3. Процесс разработки JNI
- 4. Резюме
- Русские Блоги
- Подробный Android JNI
- Подробный Android JNI
- Введение
- окружение
- Создать проект JNI с помощью Android Studio
- Анализ MainActivity под JNI
- Анализ кода C / C ++ под JNI
- Основы JNI
- Основная последовательность локальных вызовов программы
- Передача параметров между программами Java и Native
- Базовый тип передачи данных
- Примеры
- Передача строки
- Примеры
- Собственная строковая функция JNI
- UTF-8 strings & C-strings
- Передача массива базовых типов данных
- Примеры
- Функции, связанные с массивом базовых типов данных JNI
- Доступ к переменным объекта и обратным вызовам функций
- Доступ к внутренним переменным объекта
- Доступ к статическим переменным объекта
- Обратный вызов Java-функция и статическая функция
- Доступ к перегруженным функциям родительского класса
- Создание объектов и массивов объектов
- Создать объект
- Функция JNI для создания объекта (jobject):
- Массив объектов
- Локальные и глобальные ссылки
Русские Блоги
Введение в процесс разработки Android JNI
1. Что такое JNI
Полное название JNI — Java Native Interface, а на китайском он называется Java Native Interface. JNI — это протокол связи между языком JAVA и языком C / C ++. Через JNI код Java может вызывать код, написанный на C, C ++ и других языках, или, наоборот, код C, C ++ и других языков может вызывать код, написанный на Java, через JNI.
Зачем использовать JNI?
Мы знаем, что характеристики языка Java написаны один раз и используются повсюду. Кросс-платформенность — это преимущество Java, но есть свои плюсы и минусы. Кросс-платформенная особенность делает Java и базовые возможности взаимодействия недостаточно сильными, и это язык C / C ++. С другой стороны, в чем она хороша, Java может повторно использовать большое количество существующих файлов библиотеки C / C ++ через JNI, чтобы избежать повторного создания колес.
2. Что такое NDK
Полное название NDK — Native Develop Kit, которое можно перевести в локальный комплект разработчика. NDK — это набор инструментов, предоставляемый Android для разработки на C / C ++.
Какая связь между JNI и NDK?
JNI — это интерфейсный протокол, а NDK — это комплект средств разработки. У них есть одна общая черта: оба языка включают Native (локальный), и все они связаны с языком C / C ++. Тем не менее, немного настаивать на том, что они связаны с этими двумя пунктами. Слишком неохотно. Фактически, JNI — это Java, а NDK — это Android. Между ними нет взаимозависимости. Если есть какие-либо отношения, вы можете использовать NDK для быстрой разработки C / C ++, который соответствует требованиям интерфейса JNI в Android. Динамическая библиотека, удобная для вызовов Java.
Кто-то может спросить, язык разработки Android — это не язык Java, зачем нужны дополнительные средства разработки на языке C / C ++?
Вы знаете, хотя языком разработки Android является Java, ядром является Linux, а основная библиотека Linux написана на C / C ++, поэтому Google предоставляет инструменты NDK для облегчения взаимодействия между разработчиками и основной библиотекой. Однако общая разработка чисто бизнес-приложений не требует использования NDK. Если присутствуют следующие требования, вам необходимо использовать NDK:
- 1. Обеспечьте безопасность кода. Поскольку декомпилировать файл библиотеки so сложно, инкапсуляция основного кода в файл библиотеки so значительно повышает безопасность кода;
- 2. Удобно переносить свои приложения между платформами. С помощью NDK разработчики могут легко создавать динамические библиотеки для указанной платформы;
- 3. Повторно использовать существующую библиотеку с открытым исходным кодом C / C ++;
- 4. Повышение эффективности выполнения программ, особенно для некоторых приложений с интенсивными вычислениями.
3. Процесс разработки JNI
В качестве примера возьмем сложение двух чисел.Сложение двух чисел реализовано в C / C ++, а затем вызывается JNI. Это очень похоже на процесс аутсорсинга в повседневной жизни: Java не хотела делать это сама и отправила запрос на аутсорсинг, и C взял на себя эту работу.
- Первый шаг: первый шаг — выпустить требования для Java. Сначала создайте пакет с именем com.test.jnitest Project, создайте проект с именем JNIUtils из class , И объявите собственный метод в классе. код показан ниже:
nativeКлючевое слово указывает на то, что это функция, которую необходимо передать на аутсорсинг. Затем, после того как C завершит работу по аутсорсингу, в какой форме она будет использоваться для Java, используя файл библиотеки so, а затем Java загружается через System.loadLibrary («jni_method»), имя файла библиотеки sojni_methodЗначение является произвольным, если соответствие между Java и C хорошее.
- Шаг 2: Этот шаг все еще выполняется на стороне Java, и это то, что сделала сторона Java после получения задания C. Функция, которую мы хотим достичь, заключается в том, чтобы ввести два числа в два текстовых поля, нажать кнопку добавления, а затем код вызывает два числа, заполненных буквой C, для добавления функции и отображения результата в интерфейсе. XML-код макета интерфейса выглядит следующим образом :
Вызовите местный дополнительный код в Activity следующим образом:
- Третий шаг: код Java готов. Следующим шагом является передача работы сторонней организации C. Поскольку Java и C являются двумя языками, они не могут напрямую взаимодействовать друг с другом и должны обрабатываться. Процесс взаимодействия: сначала скомпилируйте исходный файл Java, чтобы получить файл .class, щелкнув меню «Сборка» в Visual Studio.Make Project, А затем найдите сгенерированный файл .class по пути, показанному на рисунке ниже. Обратите внимание, что путь несовместим с тем, что сказано в некоторых блогах. Путь к сгенерированному ими файлу .class находится в папке промежуточных классов классов.
-Шаг 4: Создайте файл .class. Язык C по-прежнему не читается, поэтому я сделаю обработку снова. Метод обработки состоит в том, чтобы получить файл заголовка C через файл .class, чтобы язык C мог его понять, и сгенерировать файл заголовка для использованияjavahКоманды можно выполнять в терминале (у меня MAC) или использовать терминал в Android Studio. На самом деле это одно и то же. Сначала войдите в каталог классов в терминале, обратите внимание на каталог классов, иначе вам будет предложено найти файл класса. Моя среда:
/Users/lan/AndroidStudioProjects/JNITest/app/build/intermediates/javac/debug/classesА затем выполните команду:
Примечание. Команда должна содержать полное имя пакета, а файл .class не может иметь суффикс «.class». Кроме того, я сообщал об ошибке, что класс не может быть найден согласно командам других блогов в Интернете, и для решения проблемы добавлен параметр -cp.
После успешного выполнения команды вы можете получить файл .h, как показано на рисунке ниже.
Содержимое созданного файла .h выглядит следующим образом:
-Шаг 5: После получения файла заголовка вы можете реализовать соответствующий код C в соответствии с файлом .h. В каталоге java создайте новую папку jni, скопируйте созданный файл .h в этот каталог, а затем создайте новый файл C с именем JNIUtils, реализуйте функцию, объявленную файлом заголовка в коде, реализация кода выглядит следующим образом:
-Шаг 6: После реализации кода C требования к аутсорсингу для выпуска Java были выполнены. Следующая задача — заставить C передать работу на аутсорсинг в форме, понятной Java. На первом этапе Java уже объяснила это и поручила ему работу. В форме файла библиотеки so следующая задача — найти способ сгенерировать файл библиотеки so. Сначала создайте файл Android.mk в каталоге jni. Функция Android.mk заключается в указании информации о конфигурации для компиляции исходного кода. Содержимое Android.mk выглядит следующим образом:
LOCAL_PATH: = $ (call my-dir), чтобы получить путь, по которому находится сам файл Android.mk, макросmy-dirПредоставляется системой компиляции, возвращает путь к текущему каталогу (каталог, в котором находится сам файл Android.mk);
include $ (CLEAR_VARS) Переменная макроса CLEAR_VARS предоставляется системой компилятора. И укажите на указанный GNU Makefile, который отвечает за очистку LOCAL_xxx вне LOCAL_PATH, например: LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES и т. Д. Зачем вам нужно выполнять эту операцию очистки, потому что все файлы управления компиляцией анализируются и выполняются одной и той же программой GNU Make, а их переменные являются глобальными, и можно избежать взаимного влияния после очистки, поэтому это утверждение должно быть сделано перед описанием каждой библиотеки;
LOCAL_MODULE: = jni_method означает библиотеку, которая будет сгенерирована. Эта библиотека является библиотекой, загруженной в java. Каждое имя библиотеки должно быть уникальным, без пробелов. Система компиляции автоматически добавляет сгенерированное окончательное имя библиотеки.libПрефикс иsoсуффикс. Например, в приведенном выше примере будет сгенерировано имяlibjni_cal.so, Если имя, определенное в LOCAL_MODULE, уже занялоlib, Система сборки не добавитlibПрефикс, например, имя — libmodule, тогда вывод системы компиляции будет libmodule.so вместо liblibmodule.so;
LOCAL_SRC_FILES: = JNIUtils.c содержит список исходных файлов C и / или C ++ для компиляции в библиотеку. Нет необходимости перечислять файлы заголовков. Система компиляции автоматически поможет нам найти зависимые файлы;
include $ (BUILD_SHARED_LIBRARY), где переменная BUILD_SHARED_LIBRARY указывает на сценарий GNU Makefile, который собирает всю информацию, которую вы определили в переменной LOCAL_XXX с момента последнего включения. Этот сценарий определяет, что компилировать и как компилировать:
- BUILD_STATIC_LIBRARY: скомпилирована как статическая библиотека
- BUILD_SHARED_LIBRARY: скомпилирован в динамическую библиотеку
- BUILD_EXECUTABLE: компилировать в исполняемую программу на языке C
- BUILD_PREBUILT: модуль предварительно скомпилирован
Последняя строка справочной системы связывает все вместе:
Седьмой шаг — создать файл Application.mk в каталоге jni с одним предложением: APP_ABI:=all , На предыдущем шаге проблема, которую решает Android.mk, заключается в том, кого компилировать, но еще не решено, для какой платформы скомпилирована. Это работа Application.mk. Общие платформы включают Arm, x86 и MIPS. Метод конфигурацииAPP_ABIВ поле установлено соответствующее значение, например, если вы хотите настроить файл so на основе платформы Arm, тогда APP_ABI := armeabi , Что касается платформы для создания, это зависит от того, на какой платформе будет работать код Java. Я установил его здесь, чтобы настроить поддержку всех платформ, и соответствующее поле APP_ABI := all 。
Восьмой шаг, подготовка к созданию файла so почти завершена, и следующее, что нужно сделать, — это использовать инструмент NDK для создания файла so. Я не буду вдаваться в подробности настройки среды NDK (процесс подбрасывания можно записать в виде блога), здесь предполагается, что среда NDK настроена. Процесс создания NDK очень прост: войдите в каталог jni в терминале, и терминал находится внизу Android Studio. После входа в каталог введите ndk-build После успешной компиляции команды в src / main / появятся еще две папки libs & obj, где libs — это сгенерированный файл библиотеки so, потому что я установил полную платформу в Application.mk, поэтому все платформы сгенерированы Если Application.mk настроен на определенную платформу, будет создан только файл so для конкретной платформы. После получения файла so C может дать Java задание.
Девятый шаг — передать файл библиотеки so на Java. Сначала создайте папку с именем jniLibs в src / main / и поместите папку so, сгенерированную на предыдущем шаге, в этот каталог. Здесь следует отметить два момента, один из которых заключается в том, какие библиотеки нужно копировать, вам нужно увидеть На каких платформах будет работать программа Android, если скопированный файл библиотеки so неверен, приложение не может быть установлено в обычном режиме, и будет запрошена ошибка несоответствия ABI. Поскольку мой эмулятор является платформой x86, я скопировал файл библиотеки so платформы x86 В jniLibs второе заключается в том, что копирование файлов является копией папки вместе, и вы не можете скопировать один файл so в jniLibs.
Десятый шаг, поскольку на первом шаге был подготовлен Java-код, теперь файл библиотеки so также копируется в указанный каталог, Java-код может быть запущен напрямую, на следующем рисунке показан результат работы симулятора.
4. Резюме
Процесс разработки JNI легко понять как аутсорсинг разработки требований между Java и C. Первое — это требование выпуска Java. native Функция объявления ключевых слов реализуется аутсорсингом и объявляет, что задача аутсорсинга передается в виде файла библиотеки so, а задача аутсорсинга Java передается языку C в форме файла заголовка. После того, как язык C будет реализован, мы найдем способ сгенерировать файл библиотеки so для передачи задачи. , И, наконец, скопируйте файл библиотеки so в указанный каталог, Java загрузится нормально, и весь процесс везде завершится.
Источник
Русские Блоги
Подробный Android JNI
Подробный Android JNI
Введение
JNI должен быть «может», что все ветераны Android не могут обойти. Причина, по которой это называется «может», заключается в том, что это сложнее, потому что он не только использует «натальный» язык Java-разработчиков для Android, но также требует от разработчиков C / C ++ имеет значительную основу, и то, как координировать время выполнения двух языков, также является одним из самых сложных моментов.
Сложность немного, но однажды пройдя ее, она, несомненно, откроет дверь в новый мир для разработчиков — openGL, openSL, OpenCV и серии превосходных и зрелых библиотек, которые выбирает Рен Джун. Он может не только вставить эффективные крылья для вашего применения, но и послужит основой для вашего притворства.
В этой статье подробно описано использование JNI в Android. Основная ссылкаhttps://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html, Тем не менее, это все на английском. Мне не нравится читать эту статью
окружение
Любая статья, в которой говорится, что программа без среды — это хулиган (я думаю, много, ^ _ ^).
Создать проект JNI с помощью Android Studio
Я считаю, что все, кто хочет изучать знания JNI, являются старыми птицами, и шаги создания проще:
Файл —–> Новый —–> Новый проект (на этом шаге необходимо проверить поддержку C ++, как показано на рисунке ниже) —-> Далее —-> Далее —-> Далее.
В отличие от обычного создания проекта, после успешного создания будут два файла native-lib.cpp и CMakeLists.txt, поддерживающие C / C ++. Будет еще один разговор о CMakeLists.txt.
TODO: CMakeLists.txt объяснить
В этой статье основное внимание уделяется взаимодействию между кодом C / C ++, представленным native-lib.cpp, и кодом Java, представленным MainActivity.java.
Текущие инструменты разработки действительно мощные, Android Studio может добавлять некоторые инструменты JNI в проект при создании проекта, и больше не нужно выполнять некоторые тривиальные команды javah, gcc и другие, освобождая руки для разработчиков Android (вы также можете сказать, Освободившийся страх), сэкономил время
Анализ MainActivity под JNI
Анализ кода C / C ++ под JNI
Код C / C ++ в JNI соответствует функции в Java, и команды имеют определенные правила.
Давайте посмотрим на соответствие между функциями Java и функциями C / C ++ в этом примере:
Название класса: com.dali.jnitest.MainActivity
Название метода: public native String stringFromJNI();
JNIEXPORT jstring JNICALL Java_com_dali_jnitest_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */)
- JNIEXPORT: ключевое слово объявления функции, которое можно использовать как метод JNI.
- jstring: возвращаемое значение функции, jstring соответствует объекту Java String.
- JNICALL: его можно рассматривать как ключевое слово, к которому обращается JNI, в фиксированном формате.
- Java_com_dali_jnitest_MainActivity_stringFromJNI: формат имени метода в функции CJava_
_ , Просто замените точки в имени пакета подчеркиванием.(JNI_arguments) - JNIEnv * env: ссылка на среду JNI, очень полезная переменная, с помощью которой вы можете вызывать все функции JNI.
- jobject / * this * /: объект вызывающей функции, эквивалентный объекту в слое Javathis
Основы JNI
Я сделал кое-какие экологические постельные принадлежности, а затем начал основной курс.
Как мы все знаем, тип данных java не согласуется с типом данных C / C ++. Типичный пример: String в java является ссылочным типом данных, но String в языке C — это массив строк, оканчивающихся на NULL. Следовательно, координация типов данных является ключевым содержанием JNI.
JNI определяет следующие типы JNI, используемые в локальном коде, соответствующие типам данных Java:
Основные типы данных Java:
В следующей таблице приведены соответствующие отношения
Тип данных JNI | тип данных Java |
---|---|
jint | int |
jbyte | byte |
jshort | short |
jlong | long |
jfloat | float |
jdouble | double |
jchar | char |
jboolean | boolean |
- Тип справочных данных Java:
Тип данных JNI | тип данных Java |
---|---|
jobject | java.lang.Object |
jclass | java.lang.Class |
jstring | java.lang.String |
jthrowable | java.lang.Throwable |
В Java тип данных в массиве соответствует типу массива JNI:
Тип данных JNI | тип данных Java |
---|---|
jintArray | int [] |
jbyteArray | byte [] |
jshortArray | short [] |
jlongArray | long [] |
jfloatArray | float [] |
jdoubleArray | double [] |
jcharArray | char [] |
jbooleanArray | boolean [] |
jobjectArray | Object [] |
Основная последовательность локальных вызовов программы
- Используйте тип данных JNI для получения параметра (параметр передается через вызов программы Java)
- Для справочных типов данных JNI преобразуйте или скопируйте параметры в локальные типы. Например: jstring в C-строку, jintArray в C int [] и т. Д. Основные типы данных, такие как jint и jdouble, могут использоваться напрямую без преобразования.
- Используйте локальные типы данных для выполнения программ.
- Создайте объект типа JNI, используемый в качестве возврата (возврата), скопируйте результаты программы в возвращаемый объект.
- Функция возвращает.
В процессе разработки программы JNI более сложным и чрезвычайно сложным является эталонный тип JNI (например, jstring , jobject , jintArray , jobjectArray И C локальные типы данных (например, C-string , int[] ). К счастью, среда JNI предоставляет большое количество функций для обработки этого преобразования.
Передача параметров между программами Java и Native
Базовый тип передачи данных
8 основных типов данных в Java могут быть переданы и использованы напрямую, потому что эти типы находятся в jni.h Подтверждено в:
Примеры
Передача строки
Примеры
JNI определяет jstring Тип для представления java из String , Последний параметр функции уровня C (тип JNI jstring ) Является ли слой Java String Ссылка передана на уровень C. Возвращаемое значение программы также jstring Типы.
Передача строк намного сложнее, чем базовые типы данных, потому что уровень Java String Является ли объект (ссылочный тип данных), но слой C string Это NULL окончание char Массив. Поэтому вам нужно использовать слой Java String (Для JNI jstring Представление) и С слой string ( char* ).
Среда JNI (по параметру JNIENV* Call) предоставляет эту функцию преобразования:
- использование const char* GetStringUTFChars(JNIEnv*, jstring, jboolean*) JNI string ( jstring ) Преобразование типов в слой C string ( char* )。
- Использовать jstring NewStringUTF(JNIEnv*, char*) Слой C string ( char* ) Для JNI string ( jstring )Типы.
Этапы реализации функции уровня C:
- От JNI jstring Получить данные и передать GetStringUTFChars() Переключиться на слой C string ( char* )Типы.
- Затем запустите программу, отобразите полученные данные параметров и верните другую строку.
- Слой C string ( char* ) Тип пройден NewStringUTF() Функция преобразования в JNI jstring Введите и верните.
Собственная строковая функция JNI
JNI поддерживает преобразование строк Unicode (16-байтовая строка) и UTF-8 (1-3-байтовая кодировка) в различные форматы. Строки в кодировке UTF-8 такие же, как строки в C NULL окончание char Массивы, используемые в программах на C / C ++.
Эти строки JNI ( jstring )за:
UTF-8 strings & C-strings
GetStringUTFChars() Функция может быть использована из данной Java jstring Создать новую строку C ( char * ). Если память не может быть выделена, функция возвращает NULL , экзамен NULL Это хорошая привычка.
Третий параметр isCopy(of jboolean *) , Это параметр «in-out», если возвращаемая строка является оригинальной java.lang.String Копия экземпляра будет установлена в JNI_TRUE , Если возвращенная строка указывает на оригинал String Прямой указатель экземпляра, он будет установлен в JNI_FALSE -В этом случае нативный код не должен изменять содержимое возвращаемой строки. Если возможно, среда выполнения JNI попытается вернуть прямой указатель, в противном случае она вернет копию. Тем не менее, мы редко заинтересованы в изменении базовой строки и часто передаем NULL-указатели.
Не используется GetStringUTFChars() Когда возвращается строка, вам нужно освободить память и ссылки, чтобы ее можно было собрать мусором, всегда вызывайте ReleaseStringUTFChars() 。
NewStringUTF() Функция создает новую строку JNI, используя данную строку C ( jstring )。
JDK 1.2 был представлен GetStringUTFRegion() , Это будет jstring (Или часть, начинающаяся с длины), скопированная в «предварительно выделенный» C char В массиве. Вы можете использовать их вместо GetStringUTFChars() , Поскольку массив C предварительно выделен, в этом нет необходимости isCopy 。
JDK 1.2 также представлен Get / ReleaseStringCritical() функция. против GetStringUTFChars() Точно так же, если возможно, он возвращает прямой указатель, в противном случае он возвращает копию. Нативный метод не должен предотвращать (для IO или другого) пару GetStringCritical() с ReleaseStringCritical() перечислить.
Для получения подробных инструкций всегда обращайтесь к «Спецификации нативного интерфейса Java» @http://docs.oracle.com/javase/7/docs/technotes/guides/jni/index.html。
Передача массива базовых типов данных
Примеры
В Java массивы ( array ) И класс ( class ) То же, что и тип справочных данных. Всего существует 9 типов массивов, включая 8 массивов базовых типов данных и один java.lang.Object Тип массива. Для 8 основных типов данных JNI определяет следующие типы данных, соответствующие им jintArray , jbyteArray , jshortArray , jlongArray , jfloatArray , jdoubleArray , jcharArray , jbooleanArray 。
Точно так же вам нужно преобразовать данные JNI и локальные массивы во время процесса кодирования, например: jintArray С C jint[] , jdoubleArray С C jdouble[] , Среда JNI предоставляет функции, которые поддерживают эти преобразования следующим образом:
JNI- «C местный код:
использование jint* GetIntArrayElements(JNIEnv *env, jintArray a, jboolean *iscopy) От JNI jintArray Получить локальный массив на языке Си jint[] 。
C локальным кодом- «JNI:
- Используйте сначала jintArray NewIntArray(JNIEnv *env, jsize len) Подать заявку на кусок памяти
- Тогда используйте void SetIntArrayRegion(JNIEnv *env, jintArray a, jsize start, jsize len, const jint *buf) Данные из локального кода C jint[] Копируется в слой JNI jintArray 。
Поскольку две вышеупомянутые функции являются специфическими для типа int, аналогично, в JNI имеется в общей сложности 8 аналогичных функций, соответствующих 8 основным типам данных.
Возвращаясь к примеру кода, типичные шаги локального кода для передачи массивов основных типов данных следующие:
- Получать данные массива из параметров JNI и преобразовывать в локальные данные кода C (например, jint[] )。
- выполнить программу.
- Преобразовать данные локального кода C (например, jdouble[] ) В массив JNI (например, jdoubleArray ) и вернуть данные JNI.
код шоу, как показано ниже:
Функции, связанные с массивом базовых типов данных JNI
Суммируется следующим образом:
- GET|Release ArrayElements() Функция может быть использована в соответствии с Java jxxxArray Создать C-код локально массив jxxx [].
- GET | Set
ArrayRegion() Может быть использован для jxxxArray (Или часть, начиная с длины), скопированная в предварительно выделенный локальный массив C jxxx [] 。
New
Array() Может использоваться для выделения новых jxxxArray , Тогда вы можете использовать Set
ArrayRegion() Функция из собственного массива jxxx [] Его содержание.
Доступ к переменным объекта и обратным вызовам функций
Доступ к внутренним переменным объекта
Примеры
Основные шаги для доступа к переменным экземпляра
- по GetObjectClass() Ссылка на объект класса функции.
- Проход из класса ссылки GetFieldID() Получить идентификатор поля переменной экземпляра для доступа. В параметрах необходимо указать имя переменной и дескриптор ее поля (или подпись). Для классов Java форма дескриптора поля — «L», а точка заменяется косой чертой (/). Например, дескриптор класса String — «Ljava / lang / String;». Для базовых типов данных используйте «I» для int, «B» для байтов, «S» для короткой, «J» для длинной, «F» для float, «D» для двойной, «C» для char и «Z» означает логическое значение. Для массивов префикс «[», например, «[Ljava / lang / Object;» означает массив Object; «[I» означает массив int.
- На основании идентификатора поля, пропуск GetObjectField() или Get
Field() Функция извлекает переменные экземпляра.
В соответствии с указанным ID поля и передать SetObjectField() или Set
Field() Функция, обновление переменных экземпляра.
Функции JNI, используемые для доступа к переменным экземпляра:
Доступ к статическим переменным объекта
Доступ к статическим переменным аналогичен доступу к переменным экземпляра, за исключением того, что вызывающая функция изменена на GetStaticFieldID() , Get | SetStaticObjectField() , Get | SetStatic
Field() какой-то тип.
Примеры
Функции JNI для доступа к статическим переменным:
Обратный вызов Java-функция и статическая функция
Примеры
Java-класс объявляет nativeMethod() Локальный метод и вызвать его nativeMethod() , В свою очередь на С этаже nativeMetho() Обратный вызов различных экземпляров и статических методов, определенных в этом классе.
Основные шаги для обратного вызова функций в Java-объектах в локальном коде
по GetObjectClass() Получить ссылку на объект класса.
по GetMethodID() И ссылка на объект класса для получения идентификатора метода. В параметрах функции необходимо указать имя и подпись функции. Формат подписи: (parameters)return-type «. Это слишком сложно, не волнуйтесь, вы можете пройти javap Инструмент (Class File Disassembler) перечисляет сигнатуры функций в коде Java, -s Для печати подписей, -p Используется для отображения закрытых членов (функций или переменных) следующим образом:
На основании идентификатора метода вы можете позвонить Call
Method() Или CallVoidMethod() Или CallObjectMethod() Типы, возвращаемые этими функциями: , void and Object , Добавить параметры (если есть) перед списком параметров. Для не возвращаемых типов возврата этот метод возвращает значение.
Функции JNI для доступа к функциям экземпляра и статическим функциям экземпляра:
Доступ к перегруженным функциям родительского класса
JNI предоставляет набор CallNonvirtual Method() Функции для вызова методов экземпляра суперкласса, которые были переопределены в этом классе (аналогично вызовам super. * MethodName * () в подклассах Java):
- по GetMethodID() Функция получает идентификатор метода.
- На основе идентификатора метода используйте объект, суперкласс и аргументы для доступа CallNonvirtual Method() функция.
Функция JNI для доступа к супер усталым выглядит следующим образом:
Создание объектов и массивов объектов
Создать объект
способен пройти NewObject() с newObjectArray() Функции построены в собственном коде jobject с jobjectArray И передать их обратно в программу Java.
Примеры
Функция JNI для создания объекта (jobject):
Массив объектов
Примеры
В отличие от необработанных массивов, которые можно обрабатывать партиями, для массивов объектов необходимо использовать Get | SetObjectArrayElement() Обрабатывать каждый элемент.
Функции JNI, используемые для создания и манипулирования массивом объектов (jobjectArray):
Локальные и глобальные ссылки
Управление цитатами имеет важное значение для написания эффективных программ. Например, мы часто используем FindClass() , GetMethodID() , GetFieldID() Чтобы получить jclass , jmethodID с jfieldID , Значение должно быть выбрано один раз и кэшировано для последующего использования, а не выполнять повторные вызовы для уменьшения издержек
JNI относится к объекту, используемому кодом C (для jobject ) Делится на две категории: локальные ссылки и глобальные ссылки:
- Создайте локальную ссылку в функции C и отпустите ее после выхода из метода. Это действительно для продолжительности локального метода. Вы также можете использовать функции JNI DeleteLocalRef() Явно лишает законной силы локальные ссылки, так что сборка мусора может выполняться в середине. Объект передается локальному методу в качестве локальной ссылки. Все объекты Java, возвращаемые функцией JNI ( jobject ) Есть местные ссылки.
- Программист прошел DeleteGlobalRef() До того, как функция JNI явно ее освободит, глобальная ссылка все еще существует. Вы можете передать функцию JNI NewGlobalRef() Создайте новую глобальную ссылку из локальной ссылки.
Примеры:
В приведенной выше программе мы используем classInteger = static_cast (env->NewGlobalRef(classInteger)); буду classInteger Станьте глобальной ссылкой, не забывайте использовать env->DeleteLocalRef(classInteger); Разыменования.
Обратите внимание, что jmethodID и jfieldID не являются заданиями и глобальные ссылки не могут быть созданы.
Источник