首页 > 解决方案 > JNI-Callback 中的“CallObjectMethod”返回 NULL

问题描述

我在 C++ 和 Java 之间有一个 JNI 接口。我想在java端的函数中将回调函数作为参数传递。稍后将在 C++ 中通过 JNI 调用它,并返回一个字符串。

这就是我所拥有的:

爪哇:

instance.LoadFileFromPath(Object callbackObject);

callbackObject 的函数是这样的:

public String CallbackTest (String str)
{
    //Log-Ausgabe
    System.out.println("CallbackString: " + str);
    return str;
}

这个对象被保存到 JNI 中的一个全局变量中:

jobject g_callbackObject;
jmethodID g_callbackMethod;
JNIEnv* g_env;

JNIEXPORT jboolean JNICALL xx_LoadFileFromPath (JNIEnv* env, jobject o, jobject callbackObject)
{
    jclass callBackClass = env->GetObjectClass(callbackObject);
    jmethodID callBackMethode = env->GetMethodID(callBackClass, "CallbackTest ", "(Ljava/lang/String;)Ljava/lang/String;");

    g_env = env;
    g_callbackObject = callbackObject;
    g_callbackMethod = callBackMethode;

    bool res = LoadFileFromPath(LoadFileFromPathCallbackWrapper);

    return res;
}

稍后在 C++ 中,我想调用 Java 函数“CallbackTest”:

char* LoadFileFromPathCallbackWrapper(char* fileName)
{
    jstring res = (jstring)g_env->CallObjectMethod(g_callbackObject, g_callbackMethod, g_env->NewStringUTF(fileName));
    const char* nativeStr = g_env->GetStringUTFChars(res, NULL);
#ifdef OS_LINUX
    char* result = strdup(nativeStr);
#else
    char* result = _strdup(nativeStr);
#endif
    g_env->ReleaseStringUTFChars(res, nativeStr);

    return result;
}

一切看起来都不错,但g_env->CallObjectMethod返回 NULL。java中的日志CallbackTest永远不会被打印出来。

我不允许更改界面。

有谁知道,可能是什么问题?

谢谢!

_____ 编辑:

谢谢,方法名称jmethodID callBackMethode = env->GetMethodID()是错误的,因为出于隐私原因我不得不更改名称。我编辑了这个问题。异常检查返回 0。

我现在尝试了以下方法:

JavaVM* g_vm;
jobject g_callbackObject;
jmethodID g_callbackMethod;
//JNIEnv* g_env;
          

JNIEXPORT jboolean JNICALL xx_LoadFileFromPath (JNIEnv* env, jobject o, jobject callbackObject)
{
    env->GetJavaVM(&g_vm);
    jint version = env->GetVersion();
    jclass callBackClass = env->GetObjectClass(callbackObject);
    jboolean check = env->ExceptionCheck(); //returns 0
    jmethodID callBackMethode = env->GetMethodID(callBackClass, "CallbackTest", "(Ljava/lang/String;)Ljava/lang/String;");
    check = env->ExceptionCheck(); //returns 0;

    //g_env = env;
    g_callbackObject = callbackObject;
    g_callbackMethod = callBackMethode;

    bool res = LoadFileFromPath(LoadFileFromPathCallbackWrapper);

   return res;
}

bool GetJniEnv(JavaVM* vm, JNIEnv **env) {
    bool did_attach_thread = false;
    *env = nullptr;
    int getEnvStat = vm->GetEnv((void**)env, JNI_VERSION_1_6);

    if (getEnvStat == JNI_EDETACHED) {
        if (vm->AttachCurrentThread((void**)env, NULL) == JNI_OK) {
            did_attach_thread = true;
        }
        else {}
    }

    return did_attach_thread;
}

char* LoadFileFromPathCallbackWrapper(char* fileName)
{
    JNIEnv* g_env;
    GetJniEnv(g_vm, &g_env);
    jstring res = (jstring)g_env->CallObjectMethod(g_callbackObject, g_callbackMethod, g_env->NewStringUTF(fileName));
    jboolean check = g_env->ExceptionCheck(); **//returns 1**

    const char* nativeStr = g_env->GetStringUTFChars(res, NULL);
#ifdef OS_LINUX
    char* result = strdup(nativeStr);
#else
    char* result = _strdup(nativeStr);
#endif
    g_env->ReleaseStringUTFChars(res, nativeStr);

    return result;
}

它仍然是同样的错误...... :(

标签: javac++callbackjava-native-interface

解决方案


推荐阅读