当前位置: 首页 > 知识库问答 >
问题:

异步调用如何获取JNI接口指针(JNIEnv*)

幸越泽
2023-03-14

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

共有2个答案

樊宏邈
2023-03-14

在使用JNI从Java到C的同步调用中,“环境”已经由JVM设置,但是从任意C线程向另一个方向发展,它可能不是

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

  • 使用获取获取 JVM 环境上下文
  • 如有必要,使用附加当前线程附加上下文
  • 像往常一样使用调用方法调用该方法
  • 使用分离当前线程分离

完整的例子。注意,我过去在博客上写过更详细的内容。

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();
}
西门威
2023-03-14

您可以使用JNIEnv-获取指向JVM(JavaVM*)的指针

    // 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

 类似资料:
  • 问题内容: 如何获得指向Java ByteBuffer内部数组的指针? PS:我这样做是为了共享Java和C ++使用的内存。 问题答案: ByteBuffer必须是直接起作用的字节缓冲区。

  • 我现在使用的是Itext PDFSmartCopy。我正在使用XMLWorker向document对象添加一些业务内容。然后我声明了一个阅读器(用于连接到此文档对象的pdf文件)。然后我用相同的文档对象和输出文件流作为参数调用PdfSmartCopy。然后使用常规步骤将页面复制到文档中, 但如果我使用一个新的文档对象ie而不添加业务内容,则这一块工作得很好。

  • 查看如下程序:nexter是一个接口类型,并且定义了一个next()方法读取下一字节。函数nextFew将nexter接口作为参数并读取接下来的num个字节,并返回一个切片:这是正确做法。但是nextFew2使用一个指向nexter接口类型的指针作为参数传递给函数:当使用next()函数时,系统会给出一个编译错误:*n.next undefined (type nexter has no fiel

  • 我试图以异步方式获取获取结果,如下所示: 但是当我看控制台时,我得到了这个: 所以我觉得当谈到console.logpromise仍然悬而未决?(有一个工具提示说“刚才评估了下面的值”,所以我猜它是在promise解决时更新的?当然,下面的代码(此处未显示)不起作用,因为它需要读取的返回值。我甚至不知道如何访问PromiseValue。 进行异步读取调用的正确方法是什么? 附言:我用的是香草JS。

  • 问题内容: 为了确定给定类型是否使用reflect包实现接口,您需要将reflect.Type传递给reflect.Type.Implements()。您如何获得这些类型之一? 作为一个例子,试图获得未初始化的os.Error(接口)类型的类型并 没有 工作(它恐慌的时候,你要调用它的种类()) 问题答案: 像这样做: 或一行:

  • 我正在为一家德国公司评估Dart,将各种Java程序移植到Dart,并对结果进行比较和分析。在浏览器中,飞镖轻松获胜。对于服务器来说,软件性能似乎是一个严重的问题(请看我的这个问题),但这基本上得到了缓解。 现在我正在移植一些“简单”的命令行工具,我没想到会有任何严重的问题,但至少有一个问题。一些工具确实会发出HTTP请求来收集一些数据,独立的Dart虚拟机只以异步方式支持它们。纵观所有我能找到的