JNI系列(3):如何得到JavaVM,JNIEnv接口

在系列(1)中講到,Java與native code的操作有兩種方式:(1)在Java中加載動態鏈接庫(2)使用JNI Invocation inteface,在native code中創建JVM

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封裝成一個函數。

JNIEnv* JNU_GetEnv()

{   

    JNIEnv* env;

    (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_2);

    return env;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章