JNI - 多线程

11

我有一个用于从C中调用Java函数的JNI包装器...我正在尝试从不同的线程调用一些方法,并且当尝试获取JNIEnv指针的新副本时出错...我在每个方法中使用的代码如下:

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

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

1个回答

16
请查阅章节Attaching to the VM文档
在您使用任何JNI函数之前,必须至少为每个本地线程调用一次AttachCurrentThread()。 在Java中创建的线程已经被附加了。
因此,在您的例子中,每当GetEnv调用失败时,请调用AttachCurrentThread(),这样就可以正常工作了。 或者确保每当您创建子线程时,都将其附加到虚拟机上。

这很简单,只是我犯了一个小错误。我只是交换了两个JNI调用的顺序,现在它完美地工作了!谢谢! - bbqchickenrobot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接