2017-08-03 15 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

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によってクリーンアップされるため、問題はありません)。 –

関連する問題