Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将对象创建移动到另一个方法后发生JNI总线错误_Java_Java Native Interface - Fatal编程技术网

Java 将对象创建移动到另一个方法后发生JNI总线错误

Java 将对象创建移动到另一个方法后发生JNI总线错误,java,java-native-interface,Java,Java Native Interface,我对JNI有一个问题,这让我花了一整天的时间,如果我不寻求帮助,可能会让我发疯 有两个短语:我从JNI方法调用一个新对象,它工作正常,但当我将此代码移动到另一个方法时,它崩溃了 更多详细信息: 我有一个简单的类,我想从JNI C/C++代码中创建它的实例: package example; public class ModelDetails { public ModelDetails() { ... } } 使用本机方法的类如下所示: package example; public

我对JNI有一个问题,这让我花了一整天的时间,如果我不寻求帮助,可能会让我发疯

有两个短语:我从JNI方法调用一个新对象,它工作正常,但当我将此代码移动到另一个方法时,它崩溃了

更多详细信息:

我有一个简单的类,我想从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\u example\ujniwrapper\u 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;

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

这个问题回答了根本问题:


您应该附加一个调试器,并找出错误的确切位置。我这样做了,正是在NewObject调用时。env、modelDetailsClass和mid的值是多少?“9”表示env中的0。它确实是@YuppieNetworking在其自己的回答中提到的“[an]另一个线程:-”)您几乎正确地观察到了它:但jmethodID不是问题所在,它始终是相同的整数值,您可以将其存储在静态变量中。这个问题只是由JNI代码返回Java时垃圾收集的jclass引起的,而且您没有深入研究为什么它只工作一次而另一次失败。如果在一个函数或另一个函数中执行代码,则与此无关。原因是您离开了JNI代码,返回Java,在Java中运行垃圾收集器,然后在静态jclass变量不再有效的地方再次调用JNI。问题的原因是,在静态C++变量中存储JC类(它是垃圾收集)的本地引用。所有本地引用仅对一个JNI函数调用有效。当JNI返回Java时,所有本地引用都将无效。
jclass    modelDetailsClass           = NULL;
jmethodID modelDetailsConstMid        = NULL;