我了解到JNI接口指针(JNIEnv*)仅在当前线程中有效.假设我在本机方法中启动了一个新线程;它如何向Java方法异步发送事件?因为这个新线程不能引用(JNIEnv*).为(JNIEnv*)存储全局变量显然行不通?

推荐答案

在JAVA从C++到C++的同步调用中,java已经设置了"环境",但是从一个任意的C++线程中走到另一个方向,它可能不是.

因此,您需要遵循以下步骤

  • 使用GetEnv获取JVM环境上下文
  • 如有必要,请使用AttachCurrentThread
  • 使用CallVoidMethod按正常方式调用该方法
  • 使用DetachCurrentThread拆下

完整的例子.请注意,我在过go 的blog页上已经详细介绍了这一点

JavaVM* g_vm;
env->GetJavaVM(&g_vm);

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();
}

C++相关问答推荐

char为16位且Short也为16位的c环境合法吗

如何确保内存分配在地址附近?

设计处理各种数据类型的方法和数据 struct

字符数组,字符指针,在一种情况下工作,但在另一种情况下不工作?

C指针算法在函数参数中的应用

为什么复合文字(C99)的返回会生成更多的汇编代码?

当多个线程在C中写入相同的文件描述符时,如何防止争用情况?

为什么GCC在每次循环迭代时都会生成一个数组的mov&S使用[]访问数组?(-03,x86)

用C宏替换strncMP函数中的参数

我在这里正确地解释了C操作顺序吗?

插座打开MacOS组件

编译器如何处理具有更复杂值的枚举?

将字符串数组传递给C中的函数:`str[dim1][str_size]`vs`*str[dim1]`

C代码可以在在线编译器上运行,但不能在Leetcode上运行

C语言中神秘的(我认为)缓冲区溢出

为什么这个分配做得不好呢?

为什么电路板被循环删除?

UpDown控制与预期相反

为什么需要struct in_addr

获取 struct 中匿名 struct 的大小