我正在尝试创建一个 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
?