好不容易 使用cygwin+windows打了個包,放到JAVA中使用。但是還是會報各種錯。
JAVA中使用.so文件
static{
System.loadLibrary("test");
//加載libtest.so
}
以上是網上的經典用法,很簡單的一句。但是用的時候還是出錯了。。。
主要還是.so路徑找不到。找了大半天,終於,問題解決了。
原因是:
windows下loadLibrary只能用來加載.dll, 可以使用 System.load("完整路徑+完整文件名") 來加載
(android程序最終是要放到手機上linux環境運行的,所以加載.so是沒有問題的。)
------------------------------以下詳細過程------------------------------------
我報的是
java.lang.UnsatisfiedLinkError: no XXXX in java.library.path
分析。(我的環境是windows)
1、路徑
單步調試跟蹤
loadLibrary 的
源碼,可以很清晰的看到。
JAVA底層會 從Path環境變量里尋找 鏈接庫文件。
--------所以首先要把
包放在Path的路徑下才能讓JAVA找到你的包。
2、包名
System.loadLibrary("XXX"); 方法傳入的包名,最終會傳給
System.mapLibraryName("XXX")
然后返回實際的文件名,從而和路徑結合找到你的庫文件。
在windows下
System.mapLibraryName("test")
返回的是"test.dll"。
--------所以在Windows環境下調用這個方法
System.loadLibrary("test");是根本找不到 .so文件的。而且如果使用libtest.dll的話,要填入 "libtest"。而不像加載.so一樣,文件名只要填"test".
如果被逼急了單純的將.so改成.dll也是不行滴,親測。
其實還有個加載方法
System.load("E:/XXX/libtest.so");
是可以使用.so的。
參數是
包的絕對路徑。
綜上,
如果想要在windows環境下使用.so 只能使用
System.load("包的絕對路徑");
在linux下,在以上規則基礎上(Linux下的JAVA源碼應該也是一樣的吧。。。)
1、路徑的變量 是 LD_LIBRARY_PATH
2、使用
loadLibrary()加載.so時,如:將.so命名為libtest.so, 參數填
loadLibrary("test")
。
相關:
1、java -Djava.library.path=. com.test.testJni
參數意思是 運行JAVA類時,臨時設置路徑為當前路徑(僅當前CMD有效),用於讓JAVA找到我的鏈接庫包。
2、 如果看不到JAVA底層源代碼,檢查是不是用的是JRE 而不是JDK.
Eclipse的話, Preferences->Java->Installed JREs 更換成JDK目錄。