Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.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
C++;调用Java对象方法:访问冲突_Java_Jvm_Java Native Interface - Fatal编程技术网

C++;调用Java对象方法:访问冲突

C++;调用Java对象方法:访问冲突,java,jvm,java-native-interface,Java,Jvm,Java Native Interface,我正在尝试为声音流类实现Java/C++绑定。为了保持示例的简单性,我将其简化为查找方法,这足以描述我的问题: public abstract class JSoundStream extends SoundStream { public abstract void seek(float timeOffset); } 对于测试,我使用以下实现: @Override public void seek(float timeOffset) { System.out.println("

我正在尝试为声音流类实现Java/C++绑定。为了保持示例的简单性,我将其简化为查找方法,这足以描述我的问题:

public abstract class JSoundStream extends SoundStream {
    public abstract void seek(float timeOffset);
}
对于测试,我使用以下实现:

@Override public void seek(float timeOffset) {
    System.out.println("seek(" + timeOffset + ")");
}
< > >代码>查找< /C>方法是回调方法,由一个本地C++函数委托,它充当流播放的任何回调函数。以具有快进功能的媒体播放器应用程序为例:

“快速前进”按钮按下->流式库调用C++回调<代码>查找< /代码> -委托到java方法<代码>查找< /COD> < /P> 请注意,这只是一个示例,既不涉及事件调度线程,也不涉及任何其他funky

当创建
JSoundStream
的实例时,将调用一个本机方法,该方法将同时保存Java VM指针(
JavaVM*
)和Java对象引用(
jobject
)。我这样做是因为我无法控制回调的确切调用时间,而且我不知道如何在没有Java引用的情况下获得JNI环境或对象。所以我在创建对象时保存了这些信息,在那里我确实有引用

<> > C++中的代码>查找< /COD>方法,我尝试调用java <代码>查找< /C> >方法:

virtual void OnSeek(float timeOffset) {
    JNIEnv* env;
    jvm->AttachCurrentThread((void**)&env, NULL);
    env->CallVoidMethod(binding, m_seek, (jfloat)timeOffset);
}
其中,
binding
是我之前获得的
seek
方法的
jobject
jvm
Java虚拟机指针和
m_seek
方法

但是,调用
CallVoidMethod
将导致
jvm.dll
中的访问冲突。所有的指针和值对于我所说的都是有效的,我确实确保了Java对象不会被垃圾收集。我认为存储
jobject
和/或javavm指针是问题的根源,但我还是不明白为什么,因为这些值在程序运行时没有改变


有人能看出我处理这件事的方式有问题吗?否则,如果不存储引用,我会调用C++对象中的java对象方法吗?< /p> ,如果

,您的方法应该是正确的。
  • 您的作业对象已通过
    binding=env->NewGlobalRef(binding\u passed\u as\u参数)检索到

  • 您不会多次从同一线程调用
    AttachCurrentThread
    ——请使用TLS存储
    JNIEnv
    指针


  • 2.是给定的,实际上我只是将其添加到上面的示例中,以避免人们告诉我我忘记了它。:)但是大约1,我会试试。在本机创建方法中,
    jobject
    作为参数传递,我存储了它,而不是像您描述的那样创建一个全局引用。@pdinklag:那么您将保留一个过期很长的本地引用,这肯定不起作用。像对待局部变量一样对待从java传递给您的任何内容。