java如何調用dll:用JNI調用C或C++動態聯接庫原來如此簡單

 

 
• 下截JNative組件

jnative.sourceforge.net/ 到這裏下載JNative開源項目,我下載的是1.3.2
• 解壓JNative-<st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899">1.3.2</st1:chsdate>.zip

獲得三個文件,分別是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。
JNativeCpp.dll Windows下用的,拷貝到windows / system32目錄下;
libJNativeCpp.so Linux下的,拷貝到系統目錄下;
JNative.jar 這是一個擴展包,導入工程LIB中或將其拷貝到jdk\jre\lib\ext 下,系統會自動加載。
• 使用說明

我的項目將使用JNative組件調用一個測試應用服務器狀態的TestAppSvr.dll文件,Dll文件中包含一個TestConnect()方法,返回一個整形的結果(1或0)

首先配置好JNative組件的windows環境:
將Native要用到JNativeCpp.dll放在系統盤的\WINDOWS\system32下

將JNative.jar導入工程中,新建一個調用類:
java 代碼
1. package com.tvjody;   
2.   
3. import java.io.File;   
4. import java.io.FileOutputStream;   
5. import java.io.IOException;   
6. import java.io.InputStream;   
7.   
8. import org.xvolks.jnative.JNative;   
9. import org.xvolks.jnative.Type;   
10. import org.xvolks.jnative.exceptions.NativeException;   
11.   
12. public class AppSvrTestConnect {   
13.   
14.     public AppSvrTestConnect() {   
15.   
16.     }   
17.        
18.     /**  
19.      * 測試應用服務器連接狀態  
20.      *   
21.      * TestConnect   
22.      * @param ip 應用服務器IP  
23.      * @param port 端口  
24.      * @param intrcpt 是否採用數據壓縮方式 1 :true 0:false  
25.      * @return int 1 :成功 0:失敗  
26.      * @throws NativeException  
27.      * @throws IllegalAccessException  
28.      */  
29.     private static final int TestConnect(String ip, int port, int intrcpt)throws NativeException, IllegalAccessException {   
30.         JNative n = null;   
31.         try {              
32.             n = new JNative("TestAppSvr.dll", "TestConnect");   
33.             n.setRetVal(Type.INT);   
34.             int i = 0;   
35.             n.setParameter(i++, Type.STRING, ip);   
36.             n.setParameter(i++, Type.INT, "" + port);   
37.             n.setParameter(i++, Type.INT, "" + intrcpt);   
38.             n.invoke();   
39.             return Integer.parseInt(n.getRetVal());   
40.         } finally {   
41.             if (n != null)   
42.                 n.dispose();   
43.         }   
44.     }   
45.     /**  
46.      * 指定Dll文件路徑,動態加載本地鏈接庫,測試應用服務器連接狀態  
47.      * setDllPath  
48.      * @param path Dll文件的路徑,不包含DLL名稱 例如:windows - d:\test\test\ unix - root/test/test/  
49.      * @param ip 應用服務器IP  
50.      * @param port 端口  
51.      * @param intrcpt 是否採用數據壓縮方式 1 :true 0:false  
52.      * @return int 1 :成功 0:失敗  
53.      * @throws NativeException  
54.      * @throws IllegalAccessException  
55.      */  
56.     public static final int TestConnectFromDllPath(String path,String ip, int port, int intrcpt) throws NativeException, IllegalAccessException{   
57.         path += "TestAppSvr.dll";   
58.         System.load(path);   
59.         return TestConnect(ip,port,intrcpt);   
60.     }   
61.     /**  
62.      * Dll文件放在JRE\bin目錄下面,ClassLoader就能通過System.loadLibrary()動態加載本地鏈接庫  
63.      * TestConnectFromDllPath  
64.      * @param ip 應用服務器IP  
65.      * @param port 端口  
66.      * @param intrcpt 是否採用數據壓縮方式 1 :true 0:false  
67.      * @return int 1 :成功 0:失敗  
68.      * @throws NativeException  
69.      * @throws IllegalAccessException  
70.      */  
71.     public static final int TestConnectFromDllPath(String ip, int port, int intrcpt) throws NativeException, IllegalAccessException{   
72.         System.loadLibrary("TestAppSvr");   
73.         return TestConnect(ip,port,intrcpt);   
74.     }   
75. }  

這個類實現了一個靜態私有方法,用來調用Dll文件中的方法返回結果

private static final int TestConnect(String ip, int port, int intrcpt)

兩個靜態公共方法,分兩種方式裝載DLL文件

public static final int TestConnectFromDllPath(String path,String ip, int port, int intrcpt) //通過DLL文件的路徑
public static final int TestConnectFromDllPath(String ip, int port, int intrcpt) //通過ClassLoader
             然後新建一個類,調用AppSvrTestConnect.java,實現方法一調用,我是將TestAppSvr.dll文件與Demo.java放在一個目錄下 ,所以得到Demo.java的路徑後就可以得到TestAppSvr.dll的路徑,調用AppSvrTestConnect.TestConnectFromDllPath()方法後就能返回正確的信息.方法二是已經將TestAppSvr.dll放在了Jre\bin目錄下,在JVM的Classloader的時候會自動加載,然後通過System.loadLibrary("TestAppSvr")就可以裝配DLL文件.
java 代碼
1. public class Demo {   
2.     public int getInfo() throws NativeException, IllegalAccessException{   
3.            
4.         String path=getClass().getResource(File.separator).getPath();          
5.         path = path.substring(1,path.length());   
6.         System.out.println(path);   //得到DLL文件的路徑   
7.            
8.         String ip = "192.168.0.48"; //服務器IP   
9.         int port = 221;             //端口   
10.         int intrcpt = 1;            //數據壓縮方式傳送,1爲採用;0爲不採用   
11.         //方法1 傳入Dll文件的路徑   
12.         //int info = AppSvrTestConnect.TestConnectFromDllPath(path, ip, port, intrcpt);   
13.            
14.         //方法2 Dll文件已經放在JRE\bin目錄下面   
15.         int info = AppSvrTestConnect.TestConnectFromDllPath(ip, port, intrcpt);   
16.            
17.         //1爲成功,0爲失敗   
18.         if (info == 1)   
19.             System.out.println("應用服務器可用。");   
20.         else  
21.             System.out.println("應用服務器不可用,請檢查IP地址和端口是否正確。");   
22.            
23.         return info;   
24.     }   
25.       

System.loadLibrary():裝載Windows\System32下或jre\bin或Tomcat\bin目錄下的本地鏈接庫

System.load():根據具體的目錄來加截本地鏈接庫,必須是絕對路徑

• 備註

上面的示例工程,因爲是例子,所以沒有大多的設計,只是實現了裝載DLL文件,調用DLL文件方法,返回信息.

JNative的詳細說明,請參考JNative的源程序和例子.

注意JVM只允許一個默認的ClassLoader來load native library,同時並不提供專門的API來unload一個loaded native library,所以在項目調試的時候,獨立啓動Web Server.

 

發佈了1 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章