使用Java調用DLL動態連結程式庫的方案通常有三種:JNI, Jawin, Jacob. 其中JNI(Java Native
Interface)是Java語言本身提供的調用本地已編譯的函數庫的方法,本身具有跨平台性,可以在不同的
機器上調用不同的本地庫。Jawin和Jacob都是sourceforge.net的開源項目,都是基於JNI技術的依賴Wi
ndows的實現,使得在Windows平台下使用COM和DLL的更加方便。
一、JNI(Java本地方法調用)
JNI的應用方案是基於Java類和本地函數相映射的。其使用DLL的步驟還是相對比較麻煩,不但涉及
到Java編程,還涉及到C/C++編程。
JNI的使用步驟是:
1. 編寫Java類,用該類將DLL對外提供的函數服務進行聲明,其中的Java方法均聲明為native,其方法
簽名可以自訂,不用實現函數體。
2. 用Javah工具將該Java類產生對應的.h標頭檔。
3. 最重要的比較麻煩的一步:編寫C/C++代碼實現.h標頭檔中聲明的函數,該C/C++代碼中包含jni.h頭文
件,並且編寫代碼時使用其中定義好的資料類型作為函數的輸入和返回資料類型進行編程。用這種方法
實現資料類型轉換。在該步驟中,可以在C/C++代碼中調用已經存在的DLL庫(當別人給我們提供一個現
成的dll控制項時,我們只知道介面,不能改變它的實現,就需要“自訂的dll”調用“現成dll”)
4. 另外編寫的Java代碼時就可以使用該Java類了。
在第3步中,編寫C/C++函數時,可以使用一個叫interface pointer的env指標來調用JNI提供的一系列(
很多)函數,用這些函數來訪問JVM的對象和資料。
使用JNI的缺點:使用比較麻煩,需要對已有的DLL進行封裝,需要對C/C++比較瞭解。
使用JNI的優點:可以跨平台叫用本地庫。
二、Jawin
官方網站:http://jawinproject.sourceforge.net/
Jawin的應用方案是基於函數調用時採用原始位元組流傳遞資料的。就是在Java中指明一個DLL中的某個函
數後,通過原始位元組流(需要考慮參數資料類型所佔的儲存位元組數及系統使用的位元組序列)傳遞給該DLL
函數需要的參數,其傳回值也是通過原始位元組流解析的方式獲得正確的值。
Jawin有一個Jawin.dll和Jawin.jar,根據開發環境不同,需要不同的配置.
使用Jawin的缺點:不方便調試,幾乎所有的錯誤都拋出同樣的異常COMException;需要對資料類型的
轉換比較瞭解;不能跨平台,對Windows的依賴性比較強。
使用Jawin的優點:方便使用,不用進行C/C++開發,不用對原始DLL進行封裝就可以方便使用。
本人體會:我在用 Jawin 調用單點的dll時,多次出現錯誤,最終調試失敗,後來查看它的官方文檔,
發現它對某些com調用不支援。
三、Jacob
官方文檔:http://danadler.com/jacob/
Jacob是Java-Com Bridge的縮寫,也可以用來調用DLL。其底層也是使用JNI實現,也具有Windows 的平
台依賴性。
該控制項調用相當方便,可以調用com和active, 幾分鐘就可以搞定,它下載後有一個dll和一個jar包,
把dll放到WIN_HOME/system32/下既可,把jar包放到工程的classpath下。
下面是我調用單點dll的案例:
import com.jacob.com.*; public class CallSSO { private static Dispatch dif; //載入單點控制項SSOCrypto.SSOCrypt.1 static { dif = new Dispatch("SSOCrypto.SSOCrypt.1"); } //產生隨機碼,調用單點的介面SSORadomGen,傳遞參數是strPlainString public static int SSORadomGen(String strPlainString) { Variant radom = Dispatch.call(dif, "SSORadomGen", new Variant(strPlainString)); return radom.getInt(); } //取的加密串,調用單點的介面SSOEncrypt,傳遞參數是strPlainString,lngRandomnum,strSvrCert public static String SSOEncrypt(String strPlainString, int lngRandomnum) { String strSvrCert ="1BQYR-YLGXV-QM439-CJSCS-TCN6V"; Variant encrypt = Dispatch.call(dif, "SSOEncrypt", new Variant(strPlainString),new Variant(lngRandomnum),new Variant(strSvrCert)); return encrypt.getString(); } }
缺點:不能跨平台,對Windows的依賴性比較強。
優點:調用相當方便,不用進行C/C++開發,不用對原始DLL進行封裝就可以方便使用。
總結:以上三種方法是現在常用的java調用dll方法,本人感覺第三種比較好用,當然,每種都有優缺
點,還有效能問題,我沒有測試比較,請大家自己試一下吧