在Mac OS X中,JNI的操做方法與網上給出的Linux中的使用方法略有小小差別。忽然之間發現,在此記之。java
網上給出的在Windows和Linux操做系統下的JNI編程教程不少,其實不管在哪一個系統中都是類似的步驟。總結以下:linux
編寫Java程序文件,要使用調用本地庫的類需在static初始化塊內使用System.loadLibrary(「庫名」)方法加載。編程
編譯該Java類得到.class文件,而且使用javah -jni 類名獲取「類名.h」頭文件。jvm
包含該頭文件並實現頭文件中聲明的方法。測試
編譯並生成本地庫文件。url
將該庫文件放置於java.library.path路徑(能夠經過System.getProperties().get(「java.library.path」)查看該路徑)下,便可正常使用該Java類。spa
惟一不一樣的處在於本地庫文件的編譯方式不一樣。操作系統
Windows中,通常使用VisualStudio IDE生成」庫名.dll」動態連接庫文件。(注意:庫文件的命名方式及其重要!)orm
Linux中使用gcc進行編譯。通常要使用-I選項包含$JAVA_HOME/include和$JAVA_HOME/include/linux,並使用-fPIC -shared -o lib庫名.so生成動態連接庫文件。教程
而在Mac OS X中,採用和Linux和有類似的作法。可是我嘗試後發現,不管我將該庫文件放置於何處,而且如何設置java.library.path都會產生java.lang.UnsatisfiedLinkError異常,說沒法找到該庫文件。網上也未找到答案。後來偶然在java.library.path路徑之一的/usr/lib/java中發現裏面有個libjdns_sd.jnilib文件。莫非這個動態庫文件必須以jnilib做爲後綴名?當即更改文件名,果真能正常運行!
完整演示(假設庫名是hello):
Linux系統中:
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -fPIC -shared -o libhello.so hello.c
Mac OS X中:
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/darwin -fPIC -shared -o libhello.jnilib hello.c
結論:Mac OS X中,欲使用JNI調用本地庫,該庫文件名稱必須是 lib庫名.jnilib,而不是以.so爲後綴名。
至於Windows和Linux中動態庫文件名到底爲什麼,本人未作測試。通常而言,應該能夠在java.library.path下的文件名中找到例證。
補充:
在用Eclipse開發時,若是java.library.path包含.(當前文件夾),則將對應本地庫文件置於項目文件夾下(src和bin的父文件夾)。
ps:
1,mac os 下,
java.libary.path:/Users/may/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
注意最後的 . 表示包括執行java 程序的當前目錄,因此 把jnilib文件放在執行類的同一個父目錄裏也能夠(父目錄不包括包目錄)
gcc 中, -f 也許是 feature 的意思吧, PIC 標識 Position-Independent-Code , 產生位置無關代碼,這正式共享庫須要的;-shared 標識產生共享代碼,通常默認包含 PIC特性。
3,動態庫能夠放進jar包, 可是隻能做爲資源文件打進去, 使用的時候須要先把動態庫文件讀出來放進系統的臨時目錄,而後才能夠load供jvm使用。