我在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)附加新创建的线程。

10-06 15:09