История должна начаться здесь - статическая регистрация
Без сравнения нет вреда. Статическая регистрация неоднократно подвергалась критике с момента ее появления. Громоздкий процесс (javah генерирует заголовочный файл), каждый раз при добавлении интерфейса шлак нужно х. Длинные названия функций, подробная идентификация. Эффективность работы низкая.При первом общении сложнее найти человека с соответствующей идентичностью в jni по детальной идентичности.Сравнивайте их по очереди.Если повезет,отношения устанавливаются после одного Если, скажем, если к концу все лилейники остынут. Когда трудно, когда пора сдаваться, пора мужчине выйти на сцену, динамическая прописка, да, это он. В JNI есть таблица сопоставления функций, которая зарегистрирована на виртуальной машине Java.Это любовь с первого взгляда, и связь настолько гладкая.
Динамическая регистрация, нарисуйте несколько кругов
Есть еще правила. Заранее создайте базу данных и немедленно общайтесь.
один. Введите метод JNI_OnLoad
После того как System.loadLibrary загружает динамическую библиотеку JNI, она вызывает функцию JNI_OnLoad для запуска динамической регистрации. Это место для регистрации.Вы не можете найти неправильное место.Если вы обратитесь в полицию, чтобы поймать вора, вы должны позвонить 119. Мне тоже очень грустно, но я ничего не могу сделать. Примечание. В одном .so может быть только один метод загрузки.
два. Изюминка метода RegisterNatives
В империи JNI я должен представить JNIEnv*, представителя JVM, который держит власть над жизнью и смертью в java.Указатель на переменную среды java представляет собой структуру, содержащую интерфейс JVM, который включает в себя необходимые для взаимодействовать с JVM и работать с объектами Java Функция. А RegisterNatives — всего лишь одна из пешек, регистратор. Но только через него можно войти в таблицу сопоставления функций. Карта функций? Не волнуйтесь, давайте не торопимся и шаг за шагом вырвем его сердце. В империи jni.h в описании есть такой абзац:
typedef struct {
const char* name; //Java中函数的名字
const char* signature; //描述了函数的参数和返回值
void* fnPtr; //函数指针,指向我们调用别人家c++的封装 JNI 函数方法
} JNINativeMethod;
Это структура данных таблицы сопоставления функций.С добавлением комментариев вроде бы и объяснять нечего.Что касается утомительного разбора исходников,как используется эта структура? Кхе-кхе-кхе, вернемся к теме, изюминке RegisterNatives, это придворная эпическая драма, тщательная верстка, грандиозные сцены. Скажем так, есть только три актера, A, B и C, которые будут играть одну из главных ролей в финале истории, где либо ты умрешь, либо я умру. Этот отрывок записан в сценарии:
/**
* 向JNI环境注册一个本地方法
* @param clazz 包含本地方法的Java类
* @param methods 本地方法描述数组
* @param nMethods 本地方法个数
* @return 成功返回0,否则注册失败
*/
jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
Неосознанно, оглядываясь назад, комментарий завершает анализ. Будьте проще, будьте проще в том, как вы говорите. Я, кто должен сотрудничать с вашим выступлением, закрываю глаза. Описание регистратора примерно такое же. Если у вас есть дополнительные потребности, пожалуйста, проведите собственное исследование.
три. Завершите метод JNI_OnUnload.
Тем, кто выходит потусоваться, рано или поздно придется расплачиваться, и огромной империи JNI однажды придет конец. Когда виртуальная машина выпустит компонент, она вызовет метод JNI_OnUnload.Все объекты, которыми она когда-то владела, например объекты, вернутся сюда на землю и превратятся в весеннюю грязь для защиты цветов. Конечно, вы также можете отказаться и оставить этот метод в стороне, тогда ядовитые грибы будут процветать в один прекрасный день, медленно и медленно, а затем бум. Оптимизация — это вариант для нас с вами.
Четыре. Моменты чудесного свидетеля
Должен сказать, в данный момент я очень взволнован. Цветы, почему вы такие красные? Вставьте код немного, с небольшими деталями:
static const char *jniClassName = "net/mapout/jni/JNILoader";
static JNINativeMethod methods[] = {
{
"sayHello", "()Ljava/lang/String;", (void*)jniSayHello},
};
static int registerNatives(JNIEnv* env) {
jclass clazz = env->FindClass(jniClassName);
if (clazz == NULL)
return JNI_FALSE;
jint methodSize = sizeof(methods) / sizeof(methods[0]);
if ( env->RegisterNatives(clazz, methods, methodSize) < 0 )
return JNI_FALSE;
return JNI_TRUE;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)
return JNI_ERR;
//注册方法
if (!registerNatives(env))
return JNI_ERR;
result = JNI_VERSION_1_6;
return result;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
JNIEnv *env = nullptr;
jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
return ;
}
//回收二手女朋友,回收... 嘿嘿嘿
}
На первый взгляд, нам нужно поддерживать массив методов, а остальное копировать и вставлять. Для небольшого сравнения:
/**
* 动态注册。命名简洁,清晰明了
*/
jstring jniSayHello(JNIEnv *env, jobject obj){
return str2jstring( env, sayHello() );
}
/**
* 静态注册。噗噗噗,一口老血喷涌而出
*/
JNIEXPORT jstring JNICALL Java_net_mapout_jni_JNILoader_sayHello
(JNIEnv *env, jclass jclass){
return str2jstring( env, sayHello() );
}
Еще одно замечание. Для кода нет комментария, который не может быть понятен. Если есть, используйте два комментария. Чтобы поговорить о деталях, функция здесь имеет 2 параметра, JNIEnv * был объяснен и jobject. Грубо говоря, если нативный метод не имеет статики, то он является экземпляром класса, а если он вооружен статикой, то он будет улучшен эволюцией и станет экземпляром объекта класса класса. Динамическая регистрация, вот что это такое, пора показать свою силу.