Это вопрос, связанный с предыдущим сообщением, но этот пост был решен, и теперь я хотел изменить направление вопроса.
При работе с JNI необходимо задать объект JNIEnv
для jclass
и jmethodID
для каждого класса и метода, которые будут использоваться в коде C/С++. Чтобы быть ясным, я хочу называть Java-конструкторы или методы из C/С++.
Поскольку связь с Java на C/С++ (и наоборот) является дорогостоящей, изначально я думал, что одним из способов свести к минимуму это было повторное использование jclass
и jmethodID
. Поэтому я сохранил эти экземпляры в глобальных переменных следующим образом:
jclass someClass = NULL;
jmethodID someMethod = NULL;
JNIEXPORT jobject JNICALL Java_example_method1(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java (for example, thru NewObject)
}
JNIEXPORT jobject JNICALL Java_example_method2(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java again
}
Более конкретный (и полезный) пример, который я использую для исключения исключений из любого места в своих функциях JNI:
jclass jniExceptionClass = NULL;
void throwJavaException(JNIEnv *env, const char* msg) {
if (!jniExceptionClass) {
jniExceptionClass = env->FindClass("example/JNIRuntimeException");
}
if (jniExceptionClass)
env->ThrowNew(jniExceptionClass, msg);
}
}
Проблема в том, что я продолжал использовать этот шаблон и получил ошибку сегментации, которая была решена только путем повторного использования этих переменных (это было решением предыдущего сообщения).
Вопросы:
- Почему не разрешено повторно использовать
jclass
иjmethodID
через различные функции JNI? Я думал, что эти ценности всегда совпадают. - Просто для любопытства: каково влияние/накладные расходы на инициализацию всех необходимых
jclass
иjmethodID
для каждой функции JNI?