2016-04-10 28 views
0

と無効jオブジェクトの使用をthrowed呼ば:なぜCallVoidMethodが、私はこれを行うにしようとすると、私は、JNIの初心者だJNI

JNIEXPORT jstring JNICALL Java_com_example_kalexjune_digitalimage_MainActivity_getBalanceMatrix(JNIEnv *env, 
                     jobject instance) { 
    // TODO 
    jclass jcs; 
    jmethodID mid; 
    jstring arg; 
    jobject mobj; 
    mobj = (*env)->NewGlobalRef(env,instance); 
    jcs = (*env)->GetObjectClass(env,instance); 
    mid = (*env)->GetMethodID(env,jcs,"setMatrix","(Ljava/lang/String;)V"); 
    if(mid!=0){ 
     (*env)->CallVoidMethod(env,mobj,mid,arg); 

     const char * ss = (*env)->GetStringUTFChars(env,arg,0); 
     printf("from native: %s\n",ss); 
    } 

    return (*env)->NewStringUTF(env, "hello,i'm from native"); 
} 

それが記録されています:

JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7f49b9dd2240 
... 
libart.so (art::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*,... 
lib64/libart.so (art::CheckJNI::CallVoidMethod(_JNIEnv*, _jobject*, _jmethodID*, ...)+151)  
digitalimage-1/lib/x86_64/libdigital-jni.so (Java_com_example_kalexjune_digitalimage_MainActivity_getBalanceMatrix+174) 

私の質問は:

名前付きインスタンスが無効なparamを意味しますか?

問題を解決するにはどうすればよいですか?

(私の下手な英語を忘れて.. :)

+1

あなたのコードにはすべてのエラーチェックがありません。 * JNI呼び出しごとに*の結果をチェックし、失敗した場合はその結果の例外を表示またはスローする必要があります。注意インスタンスメソッドを呼び出すために 'GlobalRef'を作成する必要はありません。これらは希少な資源です:それらを浪費しないでください。 – EJP

答えて

1

あなたは簡単にJNIエラーが発生する可能性が未初期化jstringオブジェクトを、持っているようです。 JNI関数は[out]パラメータとしてjstringを使用できません。実際には、任意のJavaメソッドのパラメータjava.lang.Stringは "不変"です。あなたはあなたの作品を

mid = (*env)->GetMethodID(env,jcs,"setMatrix","()Ljava/lang/String;"); 
  
arg = (*env)->CallObjectMethod(env, mobj, mid); 
const char *ss = (*env)->GetStringUTFChars(env, arg, 0); 

として書き直すことができます(もちろんこれはJava側でも変更が必要です)。

コードスニペットには、ReleaseStringUTFChars()を呼び出す必要があります。printfの出力は無効になります。代わりに__android_log_print()を使用してください。

関連する問題