Akh*_*esh 69 c java java-native-interface multithreading
我了解到JNI接口指针(JNIEnv*)仅在当前线程中有效.假设我在本机方法中启动了一个新线程; 它如何异步发送事件到Java方法?由于这个新线程不能有(JNIEnv*)的引用.为(JNIEnv*)存储全局变量显然不起作用?
mai*_*n-- 82
您可以使用获取指向JVM(JavaVM*
)的指针JNIEnv->GetJavaVM
.您可以安全地将该指针存储为全局变量.后来,在新的线程,您可以使用AttachCurrentThread
新的线程连接到JVM,如果你创造了它在C/C++或者干脆GetEnv
如果您创建在Java代码中的线程,我不因为JNI假定会传给你一个JNIEnv*
,然后和你不会有这个问题.
// JNIEnv* env; (initialized somewhere else)
JavaVM* jvm;
env->GetJavaVM(&jvm);
// now you can store jvm somewhere
// in the new thread:
JNIEnv* myNewEnv;
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL; // you might want to give the java thread a name
args.group = NULL; // you might want to assign the java thread to a ThreadGroup
jvm->AttachCurrentThread((void**)&myNewEnv, &args);
// And now you can use myNewEnv
Run Code Online (Sandbox Code Playgroud)
Ada*_*dam 71
在使用JNI从Java到C++的同步调用中,JVM已经设置了"环境",但是从任意C++线程转向另一个方向它可能不是
因此,您需要按照以下步骤操作
GetEnv
AttachCurrentThread
CallVoidMethod
DetachCurrentThread
完整的例子.请注意我在过去的博客中已经详细介绍了这一点
void callback(int val) {
JNIEnv * g_env;
// double check it's all ok
int getEnvStat = g_vm->GetEnv((void **)&g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
std::cout << "GetEnv: not attached" << std::endl;
if (g_vm->AttachCurrentThread((void **) &g_env, NULL) != 0) {
std::cout << "Failed to attach" << std::endl;
}
} else if (getEnvStat == JNI_OK) {
//
} else if (getEnvStat == JNI_EVERSION) {
std::cout << "GetEnv: version not supported" << std::endl;
}
g_env->CallVoidMethod(g_obj, g_mid, val);
if (g_env->ExceptionCheck()) {
g_env->ExceptionDescribe();
}
g_vm->DetachCurrentThread();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
57168 次 |
最近记录: |