我在Java代码中使用JNI来调用本机C代码这工作得很好,我在C代码中做一些处理C代码注册了一个事件监听器,这样每次在C部分准备好新的结果时都会通知我。
现在我想将结果返回到Java代码中,如下所示:
void notifyGazeEvent()
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "newGazeEvent", "(I)V");
if (mid == 0)
{
return;
}
printf("In C, about to enter Java");
(*env)->CallVoidMethod(env, obj, mid, 1);
}
现在的问题是:我不知道从哪里获取JNIEnv对象和jObject对象这是在我第一次调用C代码时传递的:
JNIEXPORT void JNICALL
Java_a_b_C_doCalculation(JNIEnv *env, jobject obj)
{
// here I register all the handlers etc,
}
但是我不知道如何传递引用,直到我的方法回调到Java。
最佳答案
要使jobject obj
保持在Java_a_b_C_doCalculation
函数之外,必须创建一个全局引用,因为在函数返回后,所有对象(JNIEnv也)都不再有效使用NewGlobalRef
可以轻松创建全局引用。
不能这样保存JNIEnv
指针,如果调用notifyGazeEvent()
的线程是用C创建的,则必须首先将该线程附加到JVM保存JavaVM *vm
中的JNI_OnLoad
指针,用GetEnv
选择JNIEnv或用AttachCurrentThread (AsDaemon)附加新创建的线程。