1. 程式人生 > >System.load(String filename)和System.loadLibrary(String libname)的區別

System.load(String filename)和System.loadLibrary(String libname)的區別

作用:

它們都可以用來裝載庫檔案,不論是JNI庫檔案還是非JNI庫檔案。在任何本地方法被呼叫之前必須先用這個兩個方法之一把相應的JNI庫檔案裝載。

其實JDK提供給使用者了兩個方法用於載入檔案,一個是System.load(String filename)方法,另外一個是System.loadLibrary(String libname)方法。

System.load

System.load 引數必須為庫檔案的絕對路徑,可以是任意路徑,例如:
System.load("C:\\Documents and Settings\\TestJNI.dll"); //Windows

System.load("/usr/lib/TestJNI.so"); //Linux

System.loadLibrary


System.loadLibrary 引數為庫檔名,不包含庫檔案的副檔名。

System.loadLibrary ("TestJNI"); //載入Windows下的TestJNI.dll本地庫

System.loadLibrary ("TestJNI"); //載入Linux下的libTestJNI.so本地庫

注意:TestJNI.dll 或 libTestJNI.so 必須是在JVM屬性java.library.path所指向的路徑中。

 

區別:

1.載入的路徑不同。

System.load(String filename)我們看JDK API的描述是“從作為動態庫的本地檔案系統中以指定的檔名載入程式碼檔案。檔名引數必須是完整的路徑名

。”,因此這個方法的引數必須是要載入的檔案的完整路徑,帶檔案字尾名。

System.loadLibrary(String libname)我們看JDK API的描述是"載入由libname引數指定的系統庫,不帶字尾名系統庫指的是java.library.path,是對映到本地系統的路徑。

用System.getProperty(String key)方法檢視一下java.library.path指向的內容

1

2

3

public static void main(String[] args){

    

System.out.println(System.getProperty("java.library.path"));

}

1

2

3

C:\Program Files\Java\jdk1.6.0_45\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;

C:\Windows;C:\Program Files (x86)\Common Files\NetSarang;C:\Program Files\Java\jdk1.6.0_45\bin;

C:\Program Files\Java\jdk1.6.0_45\jre\bin;

 

可以看出在window下就是classpath的路徑。

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,屬於別的領域的知識,我也不是很清楚,所以第二點也沒有親身試驗過。權當把這個知識點放在這兒,以後萬一遇到類似問題了,也有個解決問題的方向。

 

設定java.library.path的路徑

 

1.windows 下

(1): 設定classpath的路徑即可,一般的動態連結庫是放到c:/window/system32這個目錄下。

(2): 也可以修改環境變數,增加動態連結庫的地址。

(3): 開發時設定 eclipse的動態庫的地址, 具體參見:

http://blog.csdn.net/ty564457881/article/details/7066423

2.linux下

需要設定系統變數LD_LIBRARY_PATH來新增java.library.path。

因為JVM啟動時,會使用系統變數LD_LIBRARY_PATH的值來初始化java.library.path屬性。

java.library.path預設值
在我的機器上其預設值為:
$JAVA_HOME/jre/lib/i386/server:$JAVA_HOME/jre/lib/i386

:$JAVA_HOME/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
分析:
- 前三個都是JRE中提供的本地庫
- 後三個是作業系統的庫檔案目錄

-Djava.library.path 和 LD_LIBRARY_PATH的區別
如果使用 java -Djava.library.path=/jni/library/path 的方式設定的話,會覆蓋預設值。其值為:
/jni/library/path

如果使用 export LD_LIBRARY_PATH=/jni/library/path的方式設定的話,會追加其值到預設值中。LD_LIBRARY_PATH的值會插入到JRE本地庫之後,作業系統庫檔案目錄之前。其值為:
$JAVA_HOME/jre/lib/i386/server:$JAVA_HOME/jre/lib/i386

:$JAVA_HOME/jre/../lib/i386:/jni/library/path:/usr/java/packages/lib/i386:/lib:/usr/lib

 

轉載地址:http://www.cnblogs.com/xrq730/p/4827132.html

http://blog.sina.com.cn/s/blog_48a45b950