【发布时间】:2012-03-28 23:06:32
【问题描述】:
我正在尝试在 JAVA 中为特定的 USB 设备包装 C++ 库。 该库支持回调函数,以通知应用程序有关 USB 设备与 PC 的连接和分离。
回调函数必须具有如下特定格式:
DWORD callbackFunction(void *params);
所以我在 JNI dll 中实现了一个这样的函数,并且想在调用这个函数时调用 Java wapper 中的一个函数。
问题是我应该使用什么 JNIENV 来调用 GetObjectClass、GetMethodID 和 CallVoidMethod?
这就是我初始化 DLL 的方式。 “Set(AttachDetach)Callback”方法接受一个回调函数(第一个参数)和一个 void* 参数(第二个参数),当检测到模块附加/分离时,它们将传递给函数。
JNIEXPORT void JNICALL Java_MyPackage_MyClass_InitializeDLL
(JNIEnv *env, jobject obj, jobject callback)
{
// Storing callback object in global variable.
callBackObj = callback;
env->GetJavaVM(&jvm);
MyInstance = new MyClass();
MyInstance ->SetAttachCallback(AttachCallBack, &callBackObj);
MyInstance ->SetDetachCallback(DetachCallBack, &callBackObj);
// Testing!
jclass callBackCls = env->FindClass("MyPackage/MyClassCallBacks");
jmethodID mid = env->GetMethodID(callBackCls, "attach", "(B)V");
if (!mid)
return ; /* method not found */
//This call here works well
env->CallVoidMethod(callBackObj, mid, 5);
}
然后我在 DLL 中为 USB 设备设置了一个回调函数,当我连接设备时它被成功调用。
我在 USB 设备的附加回调中的代码是这样的:
DWORD CALLBACK AttachCallBack(CallbackParams* params)
{
JNIEnv *env;
jvm->AttachCurrentThread((void **)&env, NULL);
jclass callBackCls = env->FindClass("MyPackage/MyClassCallBacks");
jmethodID mid = env->GetMethodID(callBackCls, "attach", "(B)V");
if (!mid)
return -1; /* method not found */
// This call fails with an access violation Exception
env->CallVoidMethod(*((jobject *)(params->param)), mid, params->moduleIndex);
// This fails the same way too
env->CallVoidMethod(callBackObj, mid, 5);
jvm->DetachCurrentThread();
return 0;
}
在我使用 AttachCurrentThread 之前,我根本无法使用 JNIENV 指针。但现在该指针的任何其他使用都是成功的,而不是调用 CallVoidMethod。 你知道这里有什么问题吗?
让我补充一下 MyPackage.MyClassCallBacks 是一个接口,它的方法在另一个类中实现,即“callBackClass”
【问题讨论】:
标签: java c++ methods java-native-interface