System.load() 與 System.loadLibrary() 區別解析

原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI3ODc3NzQ4NQ==&mid=2247485074&idx=1&sn=0bf76ef73e61582b0db930261f78e775&chksm=eb509d70dc271466f9657f14ccd73ed04e58f61bed4797ae1eeb423d14e7e7b8d2ff92f06c04&scene=21#wechat_redirect

問:能簡單說說通過 JNI 使用 Native 庫時 load 與 loadLibrary 方法的區別嗎?

 

答:可以說只要接觸過 JNI 開發的就一定要掌握這個知識點。JDK 提供給了我們兩個方法用於載入庫文件,一個是 System.load(String filename) 方法,另一個是 System.loadLibrary(String libname) 方法,他們的區別主要如下分析。

  • 加載的路徑不同;System.load(String filename) 是從作爲動態庫的本地文件系統中以指定的文件名加載代碼文件,文件名參數必須是完整的路徑名且帶文件後綴;而 System.loadLibrary(String libname) 是加載由 libname 參數指定的系統庫(系統庫指的是 java.library.path,可以通過 System.getProperty(String key) 方法查看 java.library.path 指向的目錄內容),將庫名映射到實際系統庫的方法取決於系統實現,譬如在 Android 平臺系統會自動去系統目錄、應用 lib 目錄下去找 libname 參數拼接了 lib 前綴的庫文件。

  • 是否自動加載庫的依賴庫;譬如 libA.so 和 libB.so 有依賴關係,如果選擇 System.load("/sdcard/path/libA.so"),即使 libB.so 也放在 /sdcard/path/ 路徑下,load 方法還是會因爲找不到依賴的 libB.so 文件而失敗,因爲虛擬機在載入 libA.so 的時候發現它依賴於 libB.so,那麼會先去 java.library.path 下載入 libB.so,而 libB.so 並不位於 java.library.path 下,所以會報錯。解決的方案就是先 System.load("/sdcard/path/libB.so") 再 System.load("/sdcard/path/libA.so"),但是這種方式不太靠譜,因爲必須明確知道依賴關係;另一種解決方案就是使用 System.loadLibrary("A"),然後把 libA.so 和 libB.so 都放在 java.library.path 下即可。

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