接著來(lái)看下JavaMain函式坝撑,首先這是一個(gè)線(xiàn)程蜂厅,所以參數(shù)類(lèi)型是void*愉择。進(jìn)入InitializeJVM劫乱,再進(jìn)入ifn->CreateJavaVM,CreateJavaVM是函式指標(biāo)锥涕,調(diào)用hotspot中jni.cpp中的JNI_CreateJavaVM衷戈。
注意,JNI_CreateJavaVM為STDCALL层坠,函式自己清空調(diào)用堆棧殖妇。
_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args)
一路往下,注意兩個(gè)重要變數(shù)的賦值破花,thread::create_vm先跳過(guò)谦趣。其中疲吸,在下圖完成賦值,JNIInvokeInterface_裡面都是一些函式指標(biāo)前鹅。
JNIEnv是一個(gè)大結(jié)構(gòu)體摘悴,可見(jiàn)主要是對(duì)functions賦值,過(guò)程如下:
1. 執(zhí)行上述的Thread::create_vm -> JavaThread* main_thread = new JavaThread() -> initialize() ->set_jni_functions(jni_functions());
2. jni_functions返回jni_NativeInterface舰绘,jni_NativeInterface是在jni.cpp中的一個(gè)結(jié)構(gòu)體蹂喻。
3. set_jni_functions完成設(shè)置。
回到JavaMain除盏,接著調(diào)用LoadMainClass叉橱,會(huì)加在LauncherHelper.java中的checkAndLoadMain方法。之後就是hotspot層面的一些工作:GetStaticMethodID者蠕、CallStaticMethodID窃祝,這些都是宏,比較難跟蹤踱侣,舉一個(gè)例子說(shuō)明粪小。
1. 最終會(huì)調(diào)get_method_id,之前的宏採(cǎi)用預(yù)處理一下抡句,僅編譯JNI.cpp(gcc工程自行修改探膊,這裡用Visual Studio 2010)。
2. 預(yù)處理後的代碼:
3. 最後調(diào)用LEAVE()這個(gè)宏待榔,銷(xiāo)毀虛擬機(jī)的一些工作逞壁。
4. Thread::create_vm較複雜,有興趣的自己分析锐锣。