Я работаю в API вызова JNI, обращаясь к Java из C. У меня есть предварительная инициализация для кэширования более 30 классов Java в глобальные ссылки. Результаты FindClass передаются в NewGlobalRef для получения глобальной ссылки на класс. Я кеширую эти переменные класса, чтобы использовать их позже. У меня есть 30+ глобальных ссылок на классы (и более 30 глобальных methodID для конструкторов классов).
В следующем примере я удалил обработку исключений, а также вызов JNI с целью сокращения фрагмента кода. Мой рабочий код имеет проверки исключений после каждого вызова JNI, и я использую -Xcheck: jni. Вот фрагмент:
jclass aClass;
jclass bClass;
jmethodID aCtor;
jmethodID bCtor;
void getGlobalRef(const char* clazz, jclass* globalClass)
{
jclass local = (*jenv)->FindClass(jenv,clazz);
if (local)
{
*globalClass = (jclass) (*jenv)->NewGlobalRef(jenv,local);
(*jenv)->DeleteLocalRef(jenv,local);
}
}
methodID getMethodID(jclass clazz, const char* method, const char* sig)
{
return (*jenv)->GetMethodID(jenv,clazz,method,sig);
}
void initializeJNI()
{
getGlobalRef("MyProj/Testclass1", &aclass);
getGlobalRef("MyProj/Testclass2", &bclass);
.
.
aCtor = getMethodID(aclass,"<init>","()V");
bCtor = getMethodID(bclass,"<init>","(I)V");
}
Функция initializeJNI () устанавливает глобальные ссылки на jclasses и идентификаторы методов для конструкторов, а также некоторые jfieldID и некоторую инициализацию структур данных C.
После инициализации, когда я вызываю функцию JNI с использованием некоторых из кэшированных jclasses и ctor jmethodID, я получаю неверный глобальный или локальный эталонный вызов, сообщаемый из -Xcheck: jni.
В gdb я разбиваю последнюю строку initializeJNI () и печатаю все jclasses и jmethodID, а те, которые вызывают проблемы, выглядят как превращенные в мусор или сборщик мусора (т.е. 0x00 или 0x06). Возможно ли получить глобальные ссылки?
Есть предложения?