2012-04-25 15 views
10

Ho un wrapper JNI per le funzioni Java che vengono chiamate da C ... Sto provando a chiamare alcuni metodi da thread diversi e ottengo un errore quando provo ad ottenere una nuova copia del puntatore JNIEnv ... il codice che sto utilizzando è al di sotto ed è chiamato in ogni metodo:JNI - multi-thread

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

la JVM è già stata istanziata e questo (e altri metodi) eseguito quando viene chiamato dal thread principale/iniziale. Quando ottengo un valore per envRes, mantiene -2 quando si trova in una sottotrama.

risposta

15

Fare riferimento allo documentation al capitolo Attaching to the VM.

È necessario chiamare AttachCurrentThread() per ciascun thread nativo almeno una volta prima di poter utilizzare una qualsiasi delle funzioni JNI.
I thread creati in Java sono già allegati.
Quindi il tuo esempio ogni volta che la chiamata GetEnv fallisce, chiama AttachCurrentThread() e dovresti stare bene. O assicurati che quando crei un sottotraming lo colleghi alla VM.

+0

che era - molto semplice controllo da parte mia lol. Basta scambiare l'ordine delle due chiamate JNI e funziona perfettamente! Grazie! – bbqchickenrobot