Вызов метода Java из обратного вызова C ++, созданного в методе JNI, завершается неудачно - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь создать обратный вызов 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?

...