&引用;CallObjectMethod“;在JNI中,回调返回NULL 我有一个C++与java之间的JNI接口。我想在java端的函数中传递一个回调函数作为参数。这将在稍后的C++中通过JNI调用,并将返回一个字符串
这就是我所拥有的: 爪哇: callbackObject的函数如下所示:&引用;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
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;
}