我遇到了JNI的問題,它一整天都在使用我,如果我不請求幫助,可能會使我瘋狂。將對象創建移動到另一個方法後的JNI總線錯誤
在兩個短語:我從JNI方法調用NewObject,它工作正常,但是當我將此代碼移動到另一個方法時,它崩潰。
更多細節:
我有這個簡單的類,我想從JNI C/C++代碼創建它的實例:
package example;
public class ModelDetails {
public ModelDetails() { ... }
}
與天然方法的類是如如下:
package example;
public class JNIWrapper {
public native ModelDetails getModelDetails() throws SomeException;
}
下面的代碼工作非常漂亮:
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;
}
但是,因爲我已經做了很多的事情在這個功能Java_example_JNIWrapper_getModelDetails
,我決定把這個對象的創建移動到另一個功能:
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;
}
這樣,在Java_example_JNIWrapper_getModelDetails
我只是叫fillModelDetails(env, jobj);
問題是,現在我在NewObject
行發現總線錯誤。
Invalid memory access of location 0x9 eip=0x475fe1
問題: 有誰知道爲什麼我不應該從調用其他方法構造?這似乎很奇怪。
感謝您的任何提示,想法,意見......
編輯:
我剛加入-Xcheck:jni
和得到這個錯誤:
FATAL ERROR in native method: Bad global or local ref passed to JNI
at example.JNIWrapper.getModelDetails(Native Method)
所以這給了我這樣一個想法,即使用全局變量的構造函數和類ID可能會導致問題。我將這些聲明移至JNI方法中的局部變量,並且它可以工作。
這讓我感到非常驚訝,因爲我從一段時間以來一直在使用這些全局變量,從來沒有任何問題......可能會導致這個問題的原因是什麼?
你應該附加一個調試器,並找出在什麼地方你所得到的故障。 – bmargulies 2010-01-18 18:17:29
我這樣做,它正是在NewObject調用。 – YuppieNetworking 2010-01-18 19:48:12
env,modelDetailsClass和mid的值是什麼? '9'表示在env中爲0。 – bmargulies 2010-01-18 23:07:40