2017-08-03 64 views
1

我檢查了有關此錯誤的相關問題,但找不到答案。 我有以下代碼。該錯誤與調用jLog方法,如果我把它拿出來的錯誤了,所以我不明白什麼是問題 - 只是我的第一個經驗JNI:JNI - 本地方法中的致命錯誤:全局或本地引用傳遞給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");// 
} 

謝謝。

+0

我想'package.Util'是'包/ Util'一個錯字? –

+0

是的,這是一個錯字。對不起,關於那 – xtcr1st1

回答

2

A jclass只是另一個Java堆對象,這意味着它可以被垃圾回收器移動,這將使您保存的utill_class基本上是一個懸掛指針。

如果你想有一個jclass是保持有效,你需要爲它創建一個全球參考:

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

謝謝!這似乎奏效了!我知道這是一件簡單的事情,但作爲JNI的初學者,我無法弄清楚。我投了票,但不會顯示,因爲我的聲望很低。 – xtcr1st1

+0

爲了清楚地理解,如果'util_class'被定義爲全局引用,那麼它也需要被刪除,一旦不需要,對吧? – xtcr1st1

+0

@ xtcr1st1是的。本地引用在JNI調用結束時自動刪除(除非它們返回afaik)。但全局引用需要手動管理。 (儘管如果你在應用程序的整個過程中使用某些東西,這並不重要,因爲它在應用程序完成後被OS清除)。 –