前言
之前一篇文章在寫Native方法的時候,第一個步驟里面有這么一段代碼
static { System.load("D:" + File.separator + "Hello.dll"); }
其實JDK提供給用戶了兩個方法用於載入文件,一個是System.load(String filename)方法,另外一個是System.loadLibrary(String libname)方法,本文主要寫一下這兩個方法之間的區別。
區別
1、加載的路徑不同
System.load(String filename)我們看JDK API的描述是“從作為動態庫的本地文件系統中以指定的文件名加載代碼文件。文件名參數必須是完整的路徑名。”,因此這個方法的參數必須是要加載的文件的完整路徑,帶文件后綴名。
System.loadLibrary(String libname)我們看JDK API的描述是“加載由libname參數指定的系統庫。將庫名映射到實際系統庫的方法取決於系統”,這里關鍵問題就是系統庫三個字。什么是系統庫,做個實驗,修改一下static塊中的代碼,用loadLibrary方法來加載
static { System.loadLibrary("Hello"); }
運行一下,看一下結果
看到報錯了,在java.library.path中沒有找到Hello,OK,那這樣就很簡單了,我們知道了系統庫指的是java.library.path,用System.getProperty(String key)方法查看一下java.library.path指向的內容
public static void main(String[] args) { System.out.println(System.getProperty("java.library.path")); }
打印的內容太多了,就不放上來了,反正放到任意的一個路徑下都可以,注意一下不要帶后綴名。至於java.library.path指的是什么,網上很多,就不做復制黏貼的工作了。
2、這個是網上看別人寫的才知道的,假如A.dll和B.dll有依賴關系,比如A.dll靜態鏈接到B.dll,那么如果選擇System.load("D:/A.dll"),即使B.dll也放在D:/路徑下,load方法還是會因為找不到依賴的.dll文件而失敗。因為Java虛擬機在載入A.dll的時候,發現它依賴於B.dll,那么會先去java.library.path下載入B.dll,而B.dll並不位於java.library.path下。有兩個解決方案:
(1)先System.load("D:/B.dll")再System.load("D:/A.dll")
(2)把A.dll和B.dll都放在java.library.path下,然后調用System.loadLibrary("A")
不過兩個dll文件存在依賴關系,A.dll依賴於B.dll,屬於別的領域的知識,我也不是很清楚,所以第二點也沒有親身試驗過。權當把這個知識點放在這兒,以后萬一遇到類似問題了,也有個解決問題的方向。