㈠ 如何得到javaVM,JNIEnv介面
JavaVM介面
第一種方式,在載入動態鏈接庫的時候,JVM會調用JNI_OnLoad(JavaVM* jvm, void* reserved)(如果定義了該函數)。第一個參數會傳入JavaVM指針。
第二種方式,在native code中調用JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)可以得到JavaVM指針。
兩種情況下,都可以用全局變數,比如JavaVM* g_jvm來保存獲得的指針以便在任意上下文中使用。
Android系統是利用第二種方式Invocation interface來創建JVM的。
JNIEnv介面
JNI開發最常見的錯誤就是濫用了JNIEnv介面。需要強調的是JNIEnv是跟線程相關的。
在native method中,JNIEnv作為第一個參數傳入。那麼在JNIEnv不作為參數傳入的時候,該如何獲得它?JNI提供了兩個函數:(*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL)和(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2)。兩個函數都利用JavaVM介面獲得JNIEnv介面,上面已經講到如何獲得JavaVM介面。
JNI規范也說明,可以將獲得JNIEnv封裝成一個函數。
1
2
3
4
5
6
JNIEnv* JNU_GetEnv()
{
JNIEnv* env;
(*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_2);
return env;
}
㈡ android下JNI C 調用JAVA,可能是路徑問題
JNI_CreateJavaVM 這個方法是不能直接在C中調用了。你看 jni.h 的頭文件:
#if 0 /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
#endif
這三個方法都是禁止調用的 ( if 0 )
㈢ android源碼里 c調java error: undefined reference to 'JNI_CreateJavaVM'求助
android 裡面的java調用c,主要是通過ndk組件來實現的,env和vm都是系統創建好了的,可以直接調用的,看的出來樓主應該是ndk方面的初學者,對jni,ndk這些東西的關系應該沒有弄清楚,如果僅僅是一個java和c互掉的話,可以看我的帖子「ndk java 和 c 互掉」:
http://jingyan..com/article/f54ae2fcde72be1e92b84916.html
帖子集文檔,截圖,視頻於一體,涉及java調用c和c調用java兩部分,
由於感覺你是ndk的初學者,所以有時間的話,建議你看看我總結的帖子"android ndk資源匯總":
http://tieba..com/p/3439627347
希望對你有用,我是ndk吧吧主,有問題可以ndk吧留言,謝謝!
㈣ 如何在c++中調用java代碼
對於本地函數
JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj)
{
cout<<"Hello Native Test !"<<endl;
}
JNIEnv類型代表Java環境。通過這個JNIEnv*指針,就可以對Java端的代碼進行操作。如,創建Java類得對象,調用Java對象的方法,獲取Java對象的屬性等。
JNIEnv的指針會被JNI傳送到本地方法的實現函數中來對Java端的代碼進行操作
JNIEnv類中的函數:
NewObject/NewString/New<TYPE>Array :new新對象
Get/Set<TYPE>Field:獲取屬性
Get/SetStatic<TYPE>Field :獲取靜態屬性
Call<TYPE>Method/CallStatic<TYPE>Method:調用方法