學習背景:
????對接電子口岸,需要對傳輸?shù)膱笪男畔⑦M行數(shù)據(jù)加簽,他們提供了硬件加簽的USBKey。電子口岸安全組件是以DLL的方式提供,并同時支持32位、64位操作系統(tǒng),分別對應(yīng)2個不用版本的Sign64.dll文件。
對于沒有接觸過DLL文件的我來說,問題就來了:
1、什么是DLL文件?
2、Java怎么調(diào)用DLL文件的?
1、什么是DLL文件?
來源「百度百科」的解釋:
DLL(Dynamic Link Library)文件為動態(tài)鏈接庫文件,又稱“應(yīng)用程序拓展”,是軟件文件類型。在Windows中,許多應(yīng)用程序并不是一個完整的可執(zhí)行文件,它們被分割成一些相對獨立的動態(tài)鏈接庫,即DLL文件,放置于系統(tǒng)中。當我們執(zhí)行某一個程序時,相應(yīng)的DLL文件就會被調(diào)用。一個應(yīng)用程序可使用多個DLL文件,一個DLL文件也可能被不同的應(yīng)用程序使用,這樣的DLL文件被稱為共享DLL文件。
其意義:
DLL文件中存放的是各類程序的函數(shù)(子過程)實現(xiàn)過程,當程序需要調(diào)用函數(shù)時需要先載入DLL,然后取得函數(shù)的地址,最后進行調(diào)用。使用DLL文件的好處是程序不需要在運行之初加載所有代碼,只有在程序需要某個函數(shù)的時候才從DLL中取出。另外,使用DLL文件還可以減小程序的體積。
2、java怎么調(diào)用DLL文件?
JNA
什么是JNA?
來源「百度百科」的解釋:
JNA(Java Native Access )提供一組Java工具類用于在運行期間動態(tài)訪問系統(tǒng)本地庫(native library:如Window的dll)而不需要編寫任何Native/JNI代碼。開發(fā)人員只要在一個java接口中描述目標native library的函數(shù)與結(jié)構(gòu),JNA將自動實現(xiàn)Java接口到native function的映射。
優(yōu)點:
JNA可以讓你像調(diào)用一般java方法一樣直接調(diào)用本地方法。就和直接執(zhí)行本地方法差不多,而且調(diào)用本地方法還不用額外的其他處理或者配置什么的,也不需要多余的引用或者編碼,使用很方便。
3、案例分享
電子口岸的文檔
取卡號
函數(shù)原型:UINT GetCardID(BYTE* szCardID, UINT* nCardIDLen)
使用前提:extern "C" _declspec(dllimport)?UINT GetCardID(BYTE* szCardID, UINT* nCardIDLen)
功能簡介:取卡號,卡號至少分配100字節(jié)
參數(shù)說明:【out】szCardID?卡號,以\0結(jié)束
【in,out】nCardIDLen?卡號長度(該參數(shù)輸入時不能等于0,必須是szCardID實際開辟的空間大小)
返回值說明:0取卡號成功;-1卡初始化錯;-2取卡號失敗
代碼示例:
public interface CLibraryextends Library {
CLibraryINSTANCE = Native.loadLibrary("Sign64", CLibrary.class);
? ? /**
? ? * 取卡號
? ? * UINT GetCardID(BYTE* szCardID, UINT* nCardIDLen)
*
? ? * @param szCardID
? ? *? ? ? ? ? ? 卡號,以\0結(jié)束
? ? * @param nCardIDLen
? ? *? ? ? ? ? ? 卡號長度(該參數(shù)輸入時不能等于0,必須是szCardID實際開辟的空間大小)
? ? * @return 0 取卡號成功 -1 卡初始化錯 -2 取卡號失敗
*
*/
? ? int GetCardID(Memory szCardID, IntByReference nCardIDLen);
? ? /**
? ? * 取證書號
? ? * UINT GetCertNo(BYTE* szCertNo, UINT* nCertNoLen)
*
? ? * @param szCertNo
? ? *? ? ? ? ? ? 證書號,以\0結(jié)束
? ? * @param nCardIDLen
? ? *? ? ? ? ? ? 證書號長度(該參數(shù)輸入時不能等于0,必須是szCertNo實際開辟的空間大小)
? ? * @return 0 取證書號成功 -1 卡初始化錯 -2 取證書號失敗
*
*/
? ? int GetCertNo(Memory szCertNo, IntByReference nCardIDLen);
? ? /**簽名
* UINT Sign(BYTE *src, UINT srcLen, BYTE *sign, UINT* signLen, const
* char * pwd)
*
? ? * @param src
? ? *? ? ? ? ? ? 待簽名的原始數(shù)據(jù)
? ? * @param srcLen
? ? *? ? ? ? ? ? 待簽名的原始數(shù)據(jù)的長度
? ? * @param sign
? ? *? ? ? ? ? ? 簽名數(shù)據(jù),至少分配128字節(jié)
? ? * @param signLen
? ? *? ? ? ? ? ? 簽名數(shù)據(jù)長度,應(yīng)大于128個字節(jié),輸入時應(yīng)等于szSignData實際分配的空間大小
? ? * @param pwd
? ? *? ? ? ? ? ? 進行加簽的卡密碼
? ? * @return 0 簽名成功 -1 卡初始化錯 -2 卡口令不正確 -3 簽名失敗 -4 PEM編碼失敗
*
*/
? ? int Sign(String src, int srcLen, Memory sign, IntByReference signLen, String pwd);
}