如何使用JNI从C实现对Java的回调?

时间:2014-07-22 08:49:11

标签: 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", "(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。

1 个答案:

答案 0 :(得分:1)

要使jobject obj保持在Java_a_b_C_doCalculation函数之外,您必须创建一个全局引用,因为在函数返回后所有对象(也是JNIEnv)都不再有效。可以使用NewGlobalRef轻松创建全局参考。

JNIEnv指针不能以这种方式保存,如果调用notifyGazeEvent()的线程是在C中创建的,则必须首先将线程附加到JVM。保存来自JNI_OnLoadJavaVM *vm指针,并使用GetEnv获取JNIEnv或使用AttachCurrentThread (AsDaemon)附加新创建的主题。