异步调用如何获取JNI接口指针(JNIEnv *) [英] How to obtain JNI interface pointer (JNIEnv *) for asynchronous calls

查看:38
本文介绍了异步调用如何获取JNI接口指针(JNIEnv *)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have learned that the JNI interface pointer (JNIEnv *) is only valid in the current thread. Suppose I started a new thread inside a native method; how it can asynchronously send events to a Java method? As this new thread can't have a reference of (JNIEnv *). Storing a global variable for (JNIEnv *) apparently will not work?

推荐答案

在使用 JNI 从 Java 到 C++ 的环境"同步调用中已经由 JVM 设置,但是从任意 C++ 线程转向另一个方向,它可能没有

Within synchronous calls using JNI from Java to C++ the "environment" has already been setup by the JVM, however going in the other direction from an arbitrary C++ thread it may not have been

因此您需要按照以下步骤操作

Therefore you need to follow these steps

  • 使用 GetEnv
  • 获取 JVM 环境上下文
  • 如有必要,使用 AttachCurrentThread
  • 附加上下文
  • 使用CallVoidMethod
  • 正常调用方法
  • 使用DetachCurrentThread
  • 分离

完整示例.请注意,我过去曾在我的 博客

Full example. Note I have written about this in the past in more detail on my 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();
}

这篇关于异步调用如何获取JNI接口指针(JNIEnv *)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆