2012-04-25 19 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

documentationAttaching to the VMの章を参照してください。

JNI関数のいずれかを使用するには、少なくともネイティブスレッドごとにAttachCurrentThread()を呼び出す必要があります。
Javaで作成されたスレッドは既に添付されています。
GetEnvコールが失敗した場合は、AttachCurrentThread()と呼び出したほうがよいでしょう。または、サブスレッドを作成するたびに、そのサブスレッドをVMに接続するようにしてください。

+0

それはそれだった - 私の部分で非常に簡単な監督笑。 2つのJNI呼び出しの順序を入れ替えれば完全に動作します!ありがとう! – bbqchickenrobot