如何使用JNI从C实现对Java的回调?
我在Java代码中使用JNI调用本机C代码。这很好,我正在用C代码进行一些处理。C代码注册了一个事件监听器,这样每当在C部分中准备好一个新结果时,我都会收到通知 现在我想将结果返回到Java代码,如下所示:如何使用JNI从C实现对Java的回调?,java,c,java-native-interface,Java,C,Java Native Interface,我在Java代码中使用JNI调用本机C代码。这很好,我正在用C代码进行一些处理。C代码注册了一个事件监听器,这样每当在C部分中准备好一个新结果时,我都会收到通知 现在我想将结果返回到Java代码,如下所示: void notifyGazeEvent() { jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetMethodID(env, cls, "newGazeEvent"
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对象保持在Java\u a\u b\u C\u doccalculation
函数之外,必须创建一个全局引用,因为函数返回后所有对象(JNIEnv)都不再有效。使用可以轻松创建全局引用
JNIEnv
指针不能以这种方式保存,而且如果调用notifyGazeEvent()
的线程是在C中创建的,则必须首先将该线程附加到JVM。保存来自的JavaVM*vm
指针,然后使用或附加新创建的线程来获取JNIEnv。您可以检查该指针。这会给你省去很多麻烦。