2016-04-10 3 views
0

Ich bin ein Anfänger auf JNI, wenn ich versuche, dies zu tun:Warum CallVoidMethod throwed genannt Verwendung ungültiger jobject mit 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"); 
} 

es protokolliert:

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) 

Meine Frage ist:

es bedeutet, dass der Name der benannten Instanz ungültig ist?

was könnte ich tun, um mein Problem zu beheben?

(vergessen mein schlechtes Englisch .. :)

+1

Ihr Code enthält keine Fehlerüberprüfung. Sie müssen das Ergebnis von * jedem * JNI-Aufruf überprüfen und die resultierende Ausnahme anzeigen oder werfen, wenn Sie einen Fehler erhalten. Hinweis: Sie müssen kein 'GlobalRef' erstellen, um nur eine Instanzmethode aufzurufen. Das sind knappe Ressourcen: Verschwende sie nicht. – EJP

Antwort

1

Sie scheinen nicht initialisiert zu haben jstring Objekt, das leicht den JNI-Fehler verursachen könnte. Die JNI-Funktion kann jstring nicht als [out] -Parameter verwenden. Eigentlich ist java.lang.String Parameter für jede Java-Methode "unveränderlich". Du könntest dein Stück als

umschreiben (und selbstverständlich erfordert das Änderungen auf der Java-Seite auch).

Beachten Sie, dass es andere Probleme in Ihrem Code-Snippet gibt: Sie müssen ReleaseStringUTFChars() aufrufen, und Ihre printf-Ausgabe wird in void: Sie sollten stattdessen __android_log_print() verwenden.

Verwandte Themen