开发者

C++ calling Java object method: Access Violation

开发者 https://www.devze.com 2023-02-16 13:31 出处:网络
I\'m trying to implement a Java/C++ binding for a sound streaming class. To keep my example simple, I will reduce it to its seeking method, which is enough to describe my problem:

I'm trying to implement a Java/C++ binding for a sound streaming class. To keep my example simple, I will reduce it to its seeking method, which is enough to describe my problem:

public abstract class JSoundStream extends SoundStream {
    public abstract void seek(float timeOffset);
}

For testing, I use the following implementation:

@Override public void seek(float timeOffset) {
    System.out.println("seek(" + timeOffset + ")");
}

The seek method is a callback method, delegated to by a native C++ functions that serves as a callback for whatever plays the stream. Picture a media player application with a fast forward function as an example:

"Fast forward" button pressed -> Streaming library invokes C++ callback seek -> Delegate to Java method seek

Note this is just an example, neither the Event Dispatch Thread nor anything else funky is involved.

When an instance of JSoundStream gets created, a native method is called that will save back both the Java VM pointer (JavaVM*) as well as the Java object reference (jobject). I do this because I cannot control when exactly the callback is called, and I know of no way to get the JNI environment or the object live with no Java references whatsoever. So I save back that information at the time of object creation, where I do have the references.

Inside of the C++ seek method, I'm trying to invoke the Java seek method this way:

virtual void OnSeek(float timeOffset) {
    JNIEnv* env;
    jvm->AttachCurrentThread((void**)&env, NULL);
    env->CallVoidMethod(binding, m_seek, (jfloat)timeOffset);
}

Where binding is the jobject, jvm the Java VM pointer and m_seek the jmethodID of the seek method I obtained before.

However, that invocation of CallVoidMethod will result in an access violation in jvm.dll. All of the pointers an开发者_运维问答d values are valid for what I can say, and I did make sure the Java object does not get garbage collected. I believe that storing the jobject and / or the Java VM pointer is the source of the problem, but then again I cannot see why, because those values are not changing while the program is running.

Can anybody see a problem in the way I am approaching this? How else - without storing references - would I invoke a Java object method from C++ code?


Your approach should be correct, if

  1. Your jobject has been retrieved with binding = env->NewGlobalRef(binding_passed_as_argument);

  2. You do not call AttachCurrentThread from the same thread multiple times - use TLS to store the JNIEnv pointer.

0

精彩评论

暂无评论...
验证码 换一张
取 消