JNI - 本机方法中的致命错误:错误的全局或本地引用传递给JNI

时间:2017-08-03 13:06:29

标签: java c java-native-interface jnienv

我检查了有关此错误的相关问题,但无法找到答案。 我有以下代码。错误与调用jLog方法有关,如果我把它拿出来,错误就消失了,所以我不明白是什么问题 - 只是我第一次体验JNI:

static jclass util_class;
static jmethodID log_from_jni;
...
    util_class = (*env)->FindClass(env, "package/Util");
    if ((*env)->ExceptionOccurred(env)) {
        printf("Error occured when loading Util class\n");
    }
    log_from_jni = (*env)->GetStaticMethodID(env, util_class,
            "logFromJNI", "(Ljava/lang/String;)V");

    if ((*env)->ExceptionOccurred(env)) {
        printf("Error occured when loading logFromJNI method\n");
    }
...

void jLog(JNIEnv *env, char* cstr) {
    if (util_class != NULL || log_from_jni != NULL) {
        jstring str = (*env)->NewStringUTF(env, cstr);
        (*env)->CallStaticVoidMethod(env, util_class, log_from_jni, str);
    } else {
        printf(cstr);
    }

}

JNIEXPORT void JNICALL Java_package_callLog(JNIEnv * env, jobject obj) {\
    jLog(env, "JNI: Log");//
}

谢谢。

1 个答案:

答案 0 :(得分:2)

jclass只是另一个Java堆对象,这意味着它可以被垃圾收集器移动,这会使你保存的utill_class基本上成为一个悬空指针。

如果您希望jclass保持有效,则需要为其创建全局参考:

util_class = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(env, "package/Util"));