轉(zhuǎn)帖|其它|編輯:郝浩|2010-06-02 11:42:02.000|閱讀 2168 次
概述:由于項(xiàng)目要求,需要用Java調(diào)用windows的dll文件,查了一下,如果用JNI的話是比較麻煩的,在sourceforge.net上搜索了一下“Java dll”,首先出現(xiàn)的是Jnative,于是決定用它,后來(lái)也試了些別的,但還是JNative好使,簡(jiǎn)單總結(jié)見本文。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
由于項(xiàng)目要求,需要用Java調(diào)用windows的dll文件,查了一下,如果用JNI的話是比較麻煩的,在sourceforge.net上搜索了一下“Java dll”,首先出現(xiàn)的是Jnative,于是決定用它,后來(lái)也試了些別的,但還是JNative好使,簡(jiǎn)單總結(jié)如下:
Java調(diào)用動(dòng)態(tài)庫(kù)所需要關(guān)心的問題:
l 如何裝載dll文件,以及如何定位所要使用的方法;
l 數(shù)據(jù)類型是如何對(duì)應(yīng)的;
l 如何給使用的方法傳遞參數(shù);
l 如何獲取返回的值。
JNative INFO: Resource URL: //jnative.sourceforge.net/ Source Code: //sourceforge.net/projects/jnative Detailed Review: //jnative.free.fr JavaDOC: //jnative.free.fr/docs/ Version:1.3 |
一個(gè)開源的組件,通過它調(diào)用已有動(dòng)態(tài)庫(kù)中的方法就非常的方便,支持CallBack 。
為什么選擇JNative
同類的開源組件相對(duì)活躍的還有,JNA ( Java Native Access ), Jawin,Nativecall,etc.但是Jnative 相對(duì)更容易使用,它對(duì)數(shù)據(jù)類型的處理做的更好。
l JNA 需要用戶對(duì)所使用的DLL文件事先進(jìn)行封裝,才能裝載。另外需要在一個(gè)java接口中描述目標(biāo)DLL中的函數(shù)與結(jié)構(gòu),從而使JNA自動(dòng)實(shí)現(xiàn)Java接口到native function的映射,較麻煩。
l Nativecall 暫時(shí)還不知道如何裝載dll文件。
l Jawin 數(shù)據(jù)類型匹配相當(dāng)敏感,它采用一種叫做”instruction string”的格式來(lái)傳遞參數(shù),還沒有完全理解。
How to:
解壓JNative-1.3.2.zip 獲得三個(gè)文件,分別是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。
JNativeCpp.dll Windows下用的,拷到windows / system32目錄下;
libJNativeCpp.so Linux下的咚咚;
JNative.jar 這是一個(gè)擴(kuò)展包,將其copy到C:\jdk\jre\lib\ext 下(我的目錄結(jié)構(gòu)),系統(tǒng)會(huì)自動(dòng)加載。
結(jié)構(gòu)映射(Structure Mapping)
Type Length JNative class DWORD 4 org.xvolks.jnative.misc.basicStructures.LONG HWND 4 org.xvolks.jnative.misc.basicStructures.HWND COLORREF 4 org.xvolks.jnative.misc.basicStructures.LONG COLORREF* 4 org.xvolks.jnative.pointers.Pointer LPARAM 4 org.xvolks.jnative.misc.basicStructures.LPARAM LPCCHOOKPROC 4 org.xvolks.jnative.util.Callback LPCTSTR 4 org.xvolks.jnative.pointers.Pointer |
一些關(guān)鍵的類及方法
Class
作用
一般用到的方法(參數(shù)略,參考Doc)
org.xvolks.jnative.Jnative
裝載dll文件,定位函數(shù)
JNative(),setParameter(),setRetVal(),getRetVal() etc.
org.xvolks.jnative.pointers.Pointer
替代本地函數(shù)中的的指針,需要先申請(qǐng)一塊內(nèi)存空間,才能創(chuàng)建
Pointer(),dispose()
org.xvolks.jnative.pointers.memory.MemoryBlockFactory
申請(qǐng)一塊內(nèi)存空間
createMemoryBlock()
org.xvolks.jnative.exceptions.NativeException
拋出裝載,定位等方面的異常
org.xvolks.jnative.Type
列舉和管理Jnative需要的不同的數(shù)據(jù)類型
(二)
簡(jiǎn)單測(cè)試,Javadoc 下和官方網(wǎng)上有些例子,下面的是我隨便從IC讀卡程序中找了個(gè)DLL進(jìn)行的測(cè)試:
SCReader.dll 下的SCHelp_HexStringToBytes()函數(shù)原型 SCREADER_API WINAPI long SCHelp_HexStringToBytes( LPCTSTR pSrc, BYTE* pTar, int MaxCount ); |
注意:dll文件需要放到System32下,否則可能找不到
通過Jnative 用java 來(lái)調(diào)用代碼如下:
package onlyfun.dllcall; import org.xvolks.jnative.JNative; import org.xvolks.jnative.exceptions.NativeException; import org.xvolks.jnative.pointers.Pointer; import org.xvolks.jnative.pointers.memory.MemoryBlockFactory; import org.xvolks.jnative.Type; public class UserCall { /** * return 轉(zhuǎn)換成功的字節(jié)數(shù) */ static JNative Something = null; static Pointer pointer; public String getSomething(String pSrc, Pointer pTar, int MaxCount) throws NativeException, IllegalAccessException{ try{ if(Something == null){ pTar = new Pointer(MemoryBlockFactory.createMemoryBlock(36)); Something = new JNative("SCReader.DLL", "SCHelp_HexStringToBytes"); // 利用org.xvolks.jnative.JNative 來(lái)裝載 SCReader.dll,并利用其SCHelp_HexStringToBytes方法 Something.setRetVal(Type.INT); // 指定返回參數(shù)的類型 } int i=0; Something.setParameter(i++,pSrc); Something.setParameter(i++,pTar); Something.setParameter(i++,MaxCount); System.out.println("調(diào)用的DLL文件名為:"+Something.getDLLName()); System.out.println("調(diào)用的方法名為:"+Something.getFunctionName()); //傳值 Something.invoke();//調(diào)用方法 return Something.getRetVal(); }finally{ if(Something!=null){ Something.dispose();//釋放 } } } public Pointer creatPointer() throws NativeException{ pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(36)); pointer.setIntAt(0, 36); return pointer; } public static void main(String[] args) throws NativeException, IllegalAccessException { UserCall uc = new UserCall(); String result = uc.getSomething("0FFFFF", uc.creatPointer(), 100); System.err.println("轉(zhuǎn)換成功的字節(jié)數(shù)為:"+result); TestCallback.runIt(); } } |
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載