J'ai un problème avec JNI qui m'a pris toute la journée et me rendra probablement fou si je n'appelle pas à l'aide.Erreur de bus JNI après déplacement de la création d'objet vers une autre méthode
En deux phrases: j'appelle un NewObject à partir d'une méthode JNI et cela fonctionne correctement, mais lorsque j'ai déplacé ce code vers une autre méthode, il plante.
Plus de détails:
j'ai cette classe simple, et je veux créer des instances de celui-ci de la JNI C/C++ Code:
package example;
public class ModelDetails {
public ModelDetails() { ... }
}
La classe avec la méthode native est aussi suit:
package example;
public class JNIWrapper {
public native ModelDetails getModelDetails() throws SomeException;
}
Le code suivant a travaillé très bien:
jclass modelDetailsClass = NULL;
jmethodID modelDetailsConstMid = NULL;
JNIEXPORT jobject JNICALL Java_example_JNIWrapper_getModelDetails
(JNIEnv *env, jobject jobj) {
cout << "getModelDetails c++" << endl;
// ModelDetails class
if (!modelDetailsClass) { // reuse class
modelDetailsClass = env->FindClass("example/ModelDetails");
}
if (!modelDetailsClass) { // check if findclass was successful
throwJavaException(env, "Could not get class ModelDetails");
return NULL;
}
cout << "model detail class: " << modelDetailsClass << endl;
// constructor
if (!modelDetailsConstMid) { // reuse method id
modelDetailsConstMid = env->GetMethodID(modelDetailsClass, "<init>", "()V");
}
if (!modelDetailsConstMid) { // check if getmethodid was successful
throwJavaException(env, "Could not get ModelDetails constructor method id");
return NULL;
}
// create object
jobject mdetails = env->NewObject(modelDetailsClass, modelDetailsConstMid);
if (!mdetails) {
throwJavaException(env, "Could not create ModelDetails instance");
return NULL;
}
return mdetails;
}
Cependant, étant donné que je dois faire beaucoup de choses dans cette fonction Java_example_JNIWrapper_getModelDetails
, j'ai décidé de la création de cet objet à une autre fonction:
jobject fillModelDetails(JNIEnv *env, jobject jobj) {
cout << "fillModelDetails" << endl;
// ModelDetails class
if (!modelDetailsClass) { // reuse class
modelDetailsClass = env->FindClass("example/ModelDetails");
}
if (!modelDetailsClass) { // check if findclass was successful
throwJavaException(env, "Could not get class ModelDetails");
return NULL;
}
cout << "model detail class: " << modelDetailsClass << endl;
// constructor
if (!modelDetailsConstMid) { // reuse method id
modelDetailsConstMid = env->GetMethodID(modelDetailsClass, "<init>", "()V");
}
if (!modelDetailsConstMid) { // check if getmethodid was successful
throwJavaException(env, "Could not get ModelDetails constructor method id");
return NULL;
}
// create object
jobject mdetails = env->NewObject(modelDetailsClass, modelDetailsConstMid);
if (!mdetails) {
throwJavaException(env, "Could not create ModelDetails instance");
return NULL;
}
return mdetails;
}
De cette façon, dans Java_example_JNIWrapper_getModelDetails
Je viens d'appeler fillModelDetails(env, jobj);
Le problème est que maintenant j'obtiens une erreur de bus à la ligne NewObject
.
Invalid memory access of location 0x9 eip=0x475fe1
Question: Est-ce que quelqu'un sait pourquoi je ne devrais pas être un constructeur appelle d'une autre méthode? Cela semble vraiment bizarre.
Merci pour toute astuce, idée, commentaires ...
Edit:
Je viens d'ajouter -Xcheck:jni
et obtenu cette erreur:
FATAL ERROR in native method: Bad global or local ref passed to JNI
at example.JNIWrapper.getModelDetails(Native Method)
Donc, ce m'a donné l'idée que le problème pourrait être causé en utilisant le constructeur et l'ID de classe à partir d'une variable globale. J'ai déplacé ces déclarations à une variable locale dans la méthode JNI et cela fonctionne.
Cela m'étonne vraiment parce que j'ai utilisé ces variables globales depuis un certain temps maintenant et n'ai jamais eu de problèmes ... ce qui pourrait être à l'origine de ce problème?
Vous devriez joindre un débogueur et de savoir exactement où vous obtenez la faute. – bmargulies
Je l'ai fait, c'est exactement à l'appel NewObject. – YuppieNetworking
Quelles étaient les valeurs de env, modelDetailsClass et mid? ce '9' suggère un 0 dans env. – bmargulies