2012-04-25 51 views
10

我有一个从C调用的Java函数的JNI包装...我试图调用一些来自不同线程的方法,并且在尝试获取JNIEnv指针的新副本时出现错误...我使用的代码如下,被称为在每个方法:JNI - 多线程

 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。

回答

15

请参阅documentation至章节Attaching to the VM

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

+0

就是这样 - 对我来说非常简单的监督哈哈。只是交换了两个JNI调用的顺序,它完美的工作!谢谢! – bbqchickenrobot 2012-04-26 21:41:48