2

我正在尝试创建一个 C++ 回调,如果某个事件发生,该回调就会被调用。如果是这种情况,该回调应该调用 Java 方法。

为了能够调用该 Java 方法,我需要访问 JNIEnv 对象,这就是为什么我在从 Java 调用的 JNI 函数中设置所有内容的原因。

设置很简单。我在 JNI 函数中获取jclass、 thejmethodID等。代码如下所示:

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++ lambda 的位置。回调本身最终,一旦事件发生,使用该行调用 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

4

0 回答 0