2017-08-03 3 views
1

J'ai vérifié les questions liées à cette erreur, mais je n'ai pas trouvé la réponse. J'ai le code suivant. L'erreur est liée à appeler la méthode jLog et si je prends l'erreur est parti, donc je ne comprends pas ce qui est des problèmes - que ma première expérience avec JNI:JNI - ERREUR FATALE dans la méthode native: Mauvaise référence globale ou locale passée à 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");// 
} 

Merci.

+0

Je suppose que 'package.Util' est une faute de frappe pour' package/Util'? –

+0

oui, c'était une faute de frappe. désolé à ce sujet – xtcr1st1

Répondre

2

Un jclass est juste un autre objet de tas Java, ce qui signifie qu'il peut être déplacé par le garbage collector, ce qui ferait que le utill_class que vous avez enregistré essentiellement un pointeur dangling.

Si vous voulez un jclass qui reste valide, vous devez créer une référence mondiale pour elle:

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

Merci! Cela semble avoir marché! Je savais que c'était une chose simple, mais étant un débutant total avec JNI je ne pouvais pas comprendre. J'ai voté mais cela ne se verra pas car j'ai une mauvaise réputation. – xtcr1st1

+0

Pour avoir une compréhension claire, si le 'util_class' est défini comme référence globale, il doit également être supprimé une fois qu'il n'est pas nécessaire, non? – xtcr1st1

+0

@ xtcr1st1 Oui. Les références locales sont automatiquement supprimées à la fin d'un appel JNI (sauf si elles sont renvoyées afaik). Mais les références globales doivent être gérées manuellement. (Bien que si vous utilisez quelque chose pendant toute la durée de l'application, cela n'a pas vraiment d'importance, car il est nettoyé par le système d'exploitation après la fin de l'application). –