I have jni cpp class similar to this
JNIEXPORT void JNICALL Java_com_my_package_GameBridge_startGame(JNIEnv *env,
jobject obj))
{
GameBridge_Android gameBridge;
JavaVM* jvm;
int status = env->GetJavaVM(&jvm);
// global reference
jobject globalRef = env->NewGlobalRef(obj)
gameBridge.setCallback(globalRef);
gameBridge.startGame();
}
I'm trying storing reference to jobject as a global reference and whenever I need I will be able to call java methods on that object.
I decided to create pure c++ class - GameBridge_Android
C++ header looks similar to this
GameBridge_Android.h:
class GameBridge_Android : public GameBridge
{
public:
GameBridge_Android();
virtual void startGame();
virtual void restartGame();
virtual void pauseGame();
virtual void resumeGame();
virtual void setCallback(jobject obj);
protected:
jobject mCallback;
};
And its realization
GameBridge_Android.cpp:
void GameBridge_Android::restartGame(){//....}
void GameBridge_Android::resumeGame(){//....}
void GameBridge_Android::setCallback(jobject callback)
{
mCallback = callback;
}
void GameBridge_Android::pauseGame()
{
JavaVM* vm = JniHelper::getJavaVM();
JNIEnv* env;
jint rs = vm->AttachCurrentThread(&env, NULL);
jclass cls = env->FindClass("com/my/package/GameBridge");
jmethodID onPause = env->GetMethodID(cls, "onPause", "()V");
env->CallVoidMethod(mCallback, onPause);
}
And simple java GameBridge class
public class GameBridge {
public native void startGame();
public void onPause() {
Log.d("JAVA_GameBridge", "onPause called ");
}
}
I'm getting an error
art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: native code passing in reference to invalid global reference: 0x736c6576
04-08 16:33:57.889 25537-29355/com.my.package A/art﹕ art/runtime/check_jni.cc:65] in call to CallVoidMethodV
I've tried to change jobject reference to global reference but no success (probably I'm doing smth wrong here) However, when I invoke static java method, everything works perfectly ok.
PS I'm not C++ developer, so any suggestions and correction also on that part would be very appreciated.
First, check EVERY result from calls such as FindClass() and GetMethodID() against NULL. If you get a NULL, use something like "cerr..." or "fprintf( stderr, ...)" to immediately emit a very descriptive error message.
Second, it's been a few years since I tried doing something very close to what you're doing, so I'm not sure, but I don't think you can reference the jobject passed to a native non-static method call outside of the context of the call it was passed to. You may need to use a global reference from NewGlobalRef().
JNI is very unforgiving.
Here's another method for attaching a thread to the JVM: How to obtain JNI interface pointer (JNIEnv *) for asynchronous calls
I seem to remember that's more like the one I had success with.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.