11

C から呼び出される Java 関数の JNI ラッパーがあります...別のスレッドからいくつかのメソッドを呼び出そうとしていますが、JNIEnv ポインターの新しいコピーを取得しようとするとエラーが発生します...コード I' 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;
    }

JVM はすでにインスタンス化されており、メイン/初期スレッドから呼び出されると、この (および他のメソッド) が実行されます。envRes の値を取得すると、サブスレッドでは -2 が保持されます。

4

1 に答える 1

16

ドキュメントの の章を参照してくださいAttaching to the VM

AttachCurrentThread()JNI 関数を使用する前に、各ネイティブ スレッドを少なくとも 1 回呼び出す必要があります。
Java で作成されたスレッドは既にアタッチされています。
だから私はあなたの例で、GetEnv呼び出しが失敗したときはいつでもAttachCurrentThread()大丈夫です。または、サブスレッドを作成するたびに、それを VM にアタッチするようにしてください。

于 2012-04-25T11:39:39.200 に答える