简体   繁体   中英

Error while calling non static java method from c++

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM