gpt4 book ai didi

java - 将对象创建移动到另一个方法后出现 JNI 总线错误

转载 作者:搜寻专家 更新时间:2023-10-31 20:16:21 25 4
gpt4 key购买 nike

我的 JNI 问题已经困扰了我一整天,如果我不寻求帮助,我可能会发疯。

两句话:我从 JNI 方法调用 NewObject,它工作正常,但是当我将这段代码移动到另一个方法时,它崩溃了。

更多详情:

我有这个简单的类,我想从 JNI C/C++ 代码创建它的实例:

package example;

public class ModelDetails {
public ModelDetails() { ... }
}

带有native方法的类如下:

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 方法中的一个局部变量,它起作用了。

这真的让我感到惊讶,因为我从一段时间以来一直在使用这些全局变量并且从未遇到过任何问题......可能是什么导致了这个问题?

最佳答案

我会回答这个问题,因为我发现了问题,但是关于重新使用 jclassjmethodID 的另一个问题仍然存在。朝那个方向改变这个问题似乎没有组织,所以我将另开一个线程。

解决方案是使用局部变量

jclass    modelDetailsClass           = NULL;
jmethodID modelDetailsConstMid = NULL;

而不是我之前使用的全局变量。

关于java - 将对象创建移动到另一个方法后出现 JNI 总线错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2088171/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com