java JNI——多线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10314645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:31:15  来源:igfitidea点击:

JNI - multi threads

javac++multithreadingjava-native-interface

提问by bbqchickenrobot

I have a JNI wrapper for Java functions that are called from C... I'm trying to call some methods from different threads and I get an error when trying to get a new copy of the JNIEnv pointer... the code I'm using is below and is called in each method:

我有一个用于从 C 调用的 Java 函数的 JNI 包装器......我试图从不同的线程调用一些方法,但在尝试获取 JNIEnv 指针的新副本时出现错误......我的代码m using 在下面并在每个方法中调用:

        JNIEnv* GetJniEnvHandle(){
        ThreadInfo();
        JNIEnv *envLoc; 
        //if(Thread::CurrentThread->IsBackground || Thread::CurrentThread->IsThreadPoolThread)  
        jint envRes = vm->GetEnv((void**)&envLoc, JNI_VERSION_1_4);
        if(envRes == JNI_OK){
            if(ThreadId != Thread::CurrentThread->ManagedThreadId)
                jint res = vm->AttachCurrentThread((void**)&envLoc, NULL);
        }else{          
            Log("Error obtaining JNIEnv* handle");  
        }
        return envLoc;
    }

The JVM has already been instantiated and this (and other methods) run when being called from the main/initial thread. When I get a value for envRes it holds a -2 when in a sub-thread.

JVM 已经被实例化,并且这个(和其他方法)在从主/初始线程调用时运行。当我获得 envRes 的值时,它在子线程中保持 -2。

回答by mkaes

Please refer to the documentationto the chapter Attaching to the VM.

请参阅该章节的文档Attaching to the VM

You need to call AttachCurrentThread()for each native thread at least once before you can use any of the JNI functions.
Thread created in Java are already attached.
So I your example whenever the GetEnvcall fails call AttachCurrentThread()and you should be fine. Or make sure that whenver you create a sub thread you attach it to the VM.

AttachCurrentThread()在使用任何 JNI 函数之前,您需要至少为每个本机线程调用一次。
在 Java 中创建的线程已经附加。
因此,每当GetEnv呼叫失败时,我都会以您为例AttachCurrentThread(),您应该没问题。或者确保在创建子线程时将其附加到 VM。