加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 01:11:45 所属栏目:Java 来源:网络整理
导读:我有一个问题,JNI整天带我走,如果我不打电话求助,可能会让我感到疯狂. 在两个短语中:我从JNI方法调用NewObject并且它工作正常,但是当我将此代码移动到另一个方法时,它会崩溃. 更多细节: 我有这个简单的类,我想从JNI C/C++代码创建它的实例: package examp

我有一个问题,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,"

但是,由于我必须在这个函数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 ModelDetails constructor method id");
        return NULL;
    } 

    // create object
    jobject mdetails = env->NewObject(modelDetailsClass,"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;

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读