C++;调用Java对象方法:访问冲突
我正在尝试为声音流类实现Java/C++绑定。为了保持示例的简单性,我将其简化为查找方法,这足以描述我的问题: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("
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传递给您的任何内容。