2015-02-20 16 views
5

Sono molto nuovo a JNI e sto cercando di capire come funzionano certe cose prima di eseguire il porting del mio codice iOS C++. Ho avuto successo nell'ottenere uno degli esempi NDK che funzionano in Android Studio e posso vedere come Java sia in grado di chiamare le funzioni C++.NDK Android: chiamata alle funzioni Java da C++

Sono stato a cercare in giro e prendere pezzi di codice, ma non sono stato in grado di farlo funzionare nella mia specifica implementazione.

Solo per testare come funzionano le cose, ho impostato una semplice funzione di registro di testo in java, e sto provando a chiamarla dal mio codice nativo, ma ho riscontrato problemi.

Qui è la mia funzione di Java:

public static void log(String s){ 
     Log.d("Native", s); 
} 

e C++:

void Log(std::string s){ 

    JNIEnv *env; 
    g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); 

    jstring jstr1 = env->NewStringUTF(s.c_str()); 

    jclass clazz = env->FindClass("com/android/gl2jni/GL2JNILib"); 
    jmethodID mid = env->GetStaticMethodID(clazz, "log", "(Ljava/lang/String;)V"); 

    jobject obj = env->CallStaticObjectMethod(clazz, mid, jstr1); 
} 

Da quello che ho visto con diversi esempi questo dovrebbe funzionare, ma genera un errore:

29835-29849/com.android.gl2jni A/libc﹕ Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 29849 (Thread-17371) 

Mi manca qualcosa?

EDIT:

ho cambiato a GetStaticMethodID. Ma dopo l'accesso il progresso della funzione che ho scoperto che la linea che non riesce è:

g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); 

Che ho dato è perché g_JavaVM è impostato come static JavaVM* g_JavaVM = NULL; e poi mai toccato di nuovo. Sto indovinando che ho bisogno di impostare questa variabile, ma come?

+0

È possibile aggiungere __android_log_print (ANDROID_LOG_DEBUG, "myApp", "msg xxx") prima di ogni riga e scoprire quale causa causa SIGSEGV. –

+0

Non ho testato il codice, ma dato che c'è una funzione 'GetStaticMethodID' nel' JNIEnv', mi azzarderei a pensare che la tua chiamata a 'GetMethodID' non possa trovare alcun metodo non statico che corrisponda alla tua firma e poi ritorni null, che non si riesce a verificare. – zenzelezz

+0

Ho modificato del codice e aggiunto alcuni dettagli. – Bananable

risposta

7

Parte del mio problema era che non inizializzavo JavaVM. L'altra parte era che stavo usando C++, ma stavo cercando di usare le funzioni C.

Il codice di lavoro è:

Java:

public static void log(String s){ 
     Log.d("Native", s); 
} 

C++:

void Log(std::string s){ 

    JNIEnv *env; 
    g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); 

    jstring jstr1 = env->NewStringUTF(s.c_str()); 

    jclass clazz = env->FindClass("com/android/gl2jni/GL2JNILib"); 
    jmethodID mid = env->GetStaticMethodID(clazz, "log", "(Ljava/lang/String;)V"); 

    jobject obj = env->CallStaticObjectMethod(clazz, mid, jstr1); 
} 

//In some initialization function with Environment variable 

env->GetJavaVM(&g_JavaVM); 

Speriamo che questo può aiutare altre persone con lo stesso problema.

+2

Hai un errore di battitura, dovrebbe essere 'CallStaticVoidMethod()'. – Pol

+0

Ho usato javac Foo.java seguito da javap -s Foo per ottenere il nome storpiato. Vedi http://www.rgagnon.com/javadetails/java-0286.html – Glenn