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

Java JNI-本机方法中的致命错误:传递给JNI的全局或本地引用错误,java,c,java-native-interface,jnienv,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))

我检查了有关此错误的相关问题,但找不到答案。 我有以下代码。这个错误与调用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");//
}

谢谢。

A
jclass
只是另一个Java堆对象,这意味着垃圾收集器可以移动它,这将使您保存的
utill_类基本上成为一个悬空指针

如果希望保持有效的
jclass
,则需要为其创建全局引用:

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

我猜
package.Util
package/Util
的一个打字错误?是的,它是一个打字错误。对不起,谢谢!这似乎奏效了!我知道这是一件简单的事情,但是作为一个JNI的初学者,我无法理解它。我投了更高的票,但它不会显示出来,因为我的声誉很低。为了清楚地了解,如果
util_类
被定义为全局引用,那么一旦不需要它,它也需要被删除,对吗?@xtcr1st1是的。本地引用在JNI调用结束时自动删除(除非它们以AIK返回)。但是全局引用需要手动管理。(虽然如果在应用程序的整个过程中都使用某个对象,这并不重要,因为它在应用程序完成后会被操作系统清除)。JNI本地引用将被删除,但如果返回,它引用的任何对象都将在需要时保持活动状态,就像从Java方法返回一样。