2023-01-20 264
我对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方法中的局部变量,并且起作用.
这真的让我惊讶,因为我从现在开始使用这些全局变量,而且从来没有任何问题……是什么可能导致这个问题?
我会回答这个问题,因为我发现了这个问题,但是关于重复使用jclass和jmethodID的另一个问题仍然存在.在这个方向上更改这个问题似乎没有组织,所以我将打开另一个线程.
解决方案是将局部变量用于
jclass modelDetailsClass = NULL;
jmethodID modelDetailsConstMid = NULL;
而不是我之前使用的全局变量.
这个问题回答了基本问题:
为什么我不应该重复使用Jni中的JClass和/或Jmethodid?
以上所述是小编给大家介绍的将对象创建移动到另一个方法后出现JNI总线错误,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/26025.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态