我和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方法中的一个局部变量中,它就工作了。
这真的让我吃惊,因为我用这些全局变量已经有一段时间了,从来没有遇到过任何问题…是什么导致了这个问题?