Я пытаюсь создать обратный вызов C ++, который вызывается при возникновении определенного события. Этот обратный вызов должен вызывать метод Java, если это так.
Чтобы иметь возможность вызвать этот метод Java, мне нужен доступ к объекту JNIEnv, поэтому я настроил все в функция JNI, которая вызывается из Java.
. Я получаю jclass
, jmethodID
, et c. в функции JNI. Код выглядит следующим образом:
JNIEXPORT void JNICALL Java_my_customclass_register(JNIEnv* jenv, jobject obj, jlong nativePeerAddress, jstring callbackName)
{
jclass customClass = jenv->FindClass("<fully qualified class name>");
const char* methodName = jenv->GetStringUTFChars(callbackName, JNI_FALSE);
jmethodID callbackMethod = jenv->GetMethodID(customClass, methodName, "()V");
jenv->ReleaseStringUTFChars(callbackName, methodName);
reinterpret_cast<CustomClass*>(nativePeerAddress)->SetCallback([jenv, obj, callbackMethod]()
{
jenv->CallVoidMethod(obj, callbackMethod);
});
}
Строка с вызовом SetCallback
- это место, где устанавливается лямбда C ++, которая действует как обратный вызов. Сам обратный вызов в конце концов, как только происходит событие, вызывает метод Java, используя строку
jenv->CallVoidMethod(obj, callbackMethod);
Проблема, с которой я сталкиваюсь, состоит в том, что этот вызов происходит спустя много времени после завершения вышеупомянутого метода JNI. Если вызывается обратный вызов, я в конечном итоге получаю следующее сообщение об ошибке:
JNI DETECTED ERROR IN APPLICATION: use of invalid jobject
Этот вызов завершается успешно, как и ожидалось, если я перемещаю эту строку кода из обратного вызова C ++ и помещаю ее прямо под строкой
jenv->ReleaseStringUTFChars(callbackName, methodName);
Однако он не работает при выполнении из обратного вызова C ++. Я думаю, что проблема в том, что jobject
obj
длиннее действительного объекта. Я предполагаю, что это так, потому что метод JNI уже завершил и удалил jobject
(обертка C ++, а не объект Java).
Однако мне неясно, как я могу получить действительный jobject
, на котором я могу выполнить jmethodID
. obj
будет указывать на правильный Java объект, но он просто не работает таким образом.
Есть идеи, как мне получить действительный jobject
?