MacOS環境下在Java專案呼叫C++
【問題描述】某一天突然在專案遇到一個問題,要求用Java呼叫C++的方法,網上找了不少方法,踩了比較多坑才呼叫成功,於是寫這篇文章讓大家避免入坑啦~
注意,我用的是MacOS,不是Windows。
Step1. 編寫test.java
【說明】
方法用native宣告。
test.java在Image包下。
System.load是載入動態連結庫檔案,在Step5有說明。
Step2. 編譯test.java -> test.class
具體方法:開啟終端,進入test.java檔案目錄,執行$ javac test.java
【說明】生成的test.class在Image包下。
Step3. 生成.h標頭檔案 -> Image_test.h
具體方法:開啟終端,進入test.java檔案的上一層目錄,執行$ javah Image.test, Image是包名,test指的是剛剛生成的test.class
【說明】此時,會生成一個名叫Image_test.h的標頭檔案,把此標頭檔案移動到Image目錄下,也就是和test.java、test.class檔案放在一起。
Step4. 根據Image_test.h編寫c++
具體方法:用Xcode新建一個c++檔案,命名為helloWorld.cpp。
【說明】此處編寫的c++檔案有所講究
1. cpp的標頭檔案需要參考Step3生成的.h標頭檔案編寫。.h標頭檔案引入了<jni.h>,<Image_test>,所以在cpp檔案中就要include這兩個標頭檔案。
2. 參考.h標頭檔案的函式宣告,複製到cpp檔案中,把引數稍作更改。在cpp中實現此方法,這裡做一個簡單的輸出HelloWorld。
3.把cpp檔案放入Image資料夾。即test.java、test.class 、Image_test.h、helloWorld.cpp在同一個目錄Image
Step5. 生成動態連結庫(libNativeCode.jnilib)
生成之前,先做預備工作。開啟Finder,按“Shift+Command+g”,輸入路徑:“/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include”,把darwin的jni_md.h複製一份到include目錄
【生成動態連結庫】開啟終端:進入Image目錄,執行 $ g++ -shared -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include helloWorld.cpp -o libNativeCode.jnilib
【說明】
1. -l 是 i 的大寫,不是 L 的小寫。
2. helloWorld.cpp就是剛剛編寫的C++檔案。
3. libNativeCode.jnilib是動態連結庫的命名,命名規範必須是lib開頭,字尾必須是jnilib。
4. 執行命令後生成libNativeCode.jnilib,放在Image目錄下,即test.java、test.class 、Image_test.h、helloWorld.cpp、libNativeCode.jnilib 都在同一個目錄Image中。
Step6. 右鍵執行test.java,就可以列印HelloWord。大功告成。
總結一下,其實步驟就是
1. 編寫test.java
2. 編譯test.java -> test.class
3. javah命令生成.h檔案
4. 按照.h檔案函式命名格式編寫c++檔案
5. 生成動態連結庫