&引用;CallObjectMethod“;在JNI中,回调返回NULL 我有一个C++与java之间的JNI接口。我想在java端的函数中传递一个回调函数作为参数。这将在稍后的C++中通过JNI调用,并将返回一个字符串

&引用;CallObjectMethod“;在JNI中,回调返回NULL 我有一个C++与java之间的JNI接口。我想在java端的函数中传递一个回调函数作为参数。这将在稍后的C++中通过JNI调用,并将返回一个字符串,java,c++,callback,java-native-interface,Java,C++,Callback,Java Native Interface,这就是我所拥有的: 爪哇: callbackObject的函数如下所示: public String CallbackTest (String str) { //Log-Ausgabe System.out.println("CallbackString: " + str); return str; } 此对象保存到JNI中的全局变量中: jobject g_callbackObject; jmethodID g_callbackMethod; JN

这就是我所拥有的:

爪哇:

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函数“回调测试”:

看起来一切正常,但
g_env->CallObjectMethod
返回NULL。java中
CallbackTest
的日志从未打印

我不允许更改接口

有人有什么想法吗?有什么问题吗

谢谢

编辑:

谢谢,
jmethodID callBackMethode=env->GetMethodID()
中的方法名是错误的,因为出于隐私原因,我不得不更改名称。我编辑了这个问题。ExceptionCheck返回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;
}

还是一样的错误…:(

g_env=env;
This和
callBackMethode
可能是0,因为方法名称错误。请始终使用
ExceptionCheck()
。谢谢,我编辑了我的问题。您无法保存(1)
JNIEnv*
或(2)
jobjects
静态。请参阅JNI规范。因此,您在
LoadFileFromPathCallbackWrapper
中的异常检查返回true。这意味着实际存在异常。请查看它是什么。(使用
ExceptionDescripte()
快速查看,请在生产代码中使用正确的处理)
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;
}
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;
}