2012-10-04 12 views

risposta

35

Questo codice vi darà il nome della classe chiamante:

jclass cls = env->GetObjectClass(obj); 

// First get the class object 
jmethodID mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;"); 
jobject clsObj = env->CallObjectMethod(obj, mid); 

// Now get the class object's class descriptor 
cls = env->GetObjectClass(clsObj); 

// Find the getName() method on the class object 
mid = env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); 

// Call the getName() to get a jstring object back 
jstring strObj = (jstring)env->CallObjectMethod(clsObj, mid); 

// Now get the c string from the java jstring object 
const char* str = env->GetStringUTFChars(strObj, NULL); 

// Print the class name 
printf("\nCalling class is: %s\n", str); 

// Release the memory pinned char array 
env->ReleaseStringUTFChars(strObj, str); 

Nota che non ho preso alcuna azione per controllare gli errori. Questo è solo un piccolo frammento di codice che descrive come potrebbe essere fatto.


In alternativa si potrebbe fare questo invece di utilizzare il GetStringUTFChars/ReleaseStringUTFChars:

// Make sure that the buffer is large enough 
char str[128]; 
jint strlen = env->GetStringUTFLength(strObj); 
env->GetStringUTFRegion(strObj, 0, strlen, str); 
printf("\nCalling class is: %s\n", str); 

Non c'è bisogno di rilasciare in quanto la stringa viene copiata buffer locale.

+1

Penso che non dovresti usare strlen come nome di variabile dato che si tratta di una funzione C standard esistente. –

+0

In base alla mia esperienza, in realtà non è necessario i passaggi in "Prima ottenere l'oggetto di classe"; 'clsObj' e' cls' sono funzionalmente equivalenti. – shawkinaw

+0

Il codice di esempio sta perdendo orrendamente i riferimenti locali se usato "così com'è". Tutti i riferimenti a jobject e jclass devono essere cancellati. Inoltre, questa è una cattiva pratica: jclass cls = env-> GetObjectClass (obj); ... cls = env-> GetObjectClass (clsObj); Senza liberare il riferimento precedente memorizzato in cls. –

-3

Basta chiamare getName() su jclass, anche tramite JNI.

+0

vuoi dire '((* env) -> GetObjectClass (env, obj)) -> getName()'? Voglio stampare il nome della classe (che ha invocato il metodo) dal codice jni c –

+1

Ricevo un errore quando eseguo la procedura sopra o 'jclass-> getName()' –

+2

FYI - in generale, quando descrivi cosa hai finito, e quali messaggi di errore, ecc ... ti impediscono di avere successo, riceverai un aiuto migliore. La risposta dell'EJP è corretta. Senza sapere quale errore stai ricevendo, non possiamo iniziare a commentare ciò che non funziona. Ricorda che getName() restituirà un jstring ... –

7

Nel mio caso, non ho avuto l'obiettivo di ottenere la classe. Invece, volevo ottenere il nome di una determinata classe, in base alla sua firma.

Quindi, questo ha funzionato per me. Spero che possa essere d'aiuto:

// Find the class by its JNI signature 
jclass cls = env->FindClass(expectedType); 

// Get the class object's class descriptor 
jclass clsClazz = env->GetObjectClass(cls); 

// Find the getSimpleName() method in the class object 
jmethodID methodId = env->GetMethodID(clsClazz, "getSimpleName", "()Ljava/lang/String;"); 
jstring className = (jstring) env->CallObjectMethod(cls, methodId); 

// And finally, don't forget to release the JNI objects after usage!!!! 
env->DeleteLocalRef(clsClazz); 
env->DeleteLocalRef(cls); 
Problemi correlati