(一)傷不起--java調用dll

      Java 語言特性不在闡述,請參考相關文檔,但Java爲追求統一(跨平臺)而犧牲性能(不支持對IPC的訪問),從而使Java訪問底層受到侷限。java

這幾天因一個項目須要java調用到dll, java調用dll網上也有不少,隻言片語,沒有劃分或系統地闡明。本人蔘考網絡上並結合實際作一些整理,貼出來分享給你們供參考。windows

(一) Java 調用dll網絡

1. 有什麼方式可調用dllapp

  java調用dll 經常使用幾種方式:框架

1.JNI(JAVA對本地操做的一種方法就是JNI);要本身生存頭文件,較麻煩。也比較容易出錯。這裏就不在闡明使用,請參考相關文檔。
2.JNA(Java Native Access)框架是一個開源的Java框架,是SUN公司主導開發的,創建在經典的JNI的基礎之上的一個框架;須要用戶對所使用的DLL文件事先進行封裝,才能裝載。另外須要在一個java接口中描述目標DLL中的函數與結構,從而使JNA自動實現Java接口到native function的映射,較麻煩。
下載jna.jar: https://jna.dev.java.net/servlets/ProjectDocumentList?folderID=7408&expandFolder=7408&folderID=0ide

3.JNative 一個開源的組件,方便調用已有動態庫中的方法,支持CallBack 。下載地址:JNative_1.4RC2_src.zip : http://jaist.dl.sourceforge.net/sourceforge/jnative/JNative_1.4RC2_src.zip函數

JNative.jar : http://nchc.dl.sourceforge.net/sourceforge/jnative/JNative.jar性能

JNative相對於其它同類開源組件的優勢:spa

1.容易使用.net

2.對數據類型的處理作的出色

3.支持CallBack

2.Java調用動態庫注意事項:
1. 如何裝載dll文件,以及如何定位所要使用的方法;

2. 數據類型是如何對應的;

3.如何給使用的方法傳遞參數;

4. 如何獲取返回的值。

文件用途:

解壓JNative-1.4.zip 得到三個文件,分別是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar

JNativeCpp.dll Windows下用的,拷貝到windows / system32目錄下;
libJNativeCpp.so Linux下的,拷貝到系統目錄下;
JNative.jar 這是一個擴展包,導入工程LIB中或將其拷貝到jdk/jre/lib/ext 下,系統會自動加載。

一些關鍵的類及方法

通常用到的方法

1.org.xvolks.jnative.Jnative
裝載dll文件,定位函數 JNative(),setParameter(),setRetVal(),getRetVal() etc.
2.org.xvolks.jnative.pointers.Pointer
替代本地函數中的的指針,須要先申請一塊內存空間,才能建立 Pointer(),dispose()
3.org.xvolks.jnative.pointers.memory.MemoryBlockFactory
申請一塊內存空間 createMemoryBlock()
4.org.xvolks.jnative.exceptions.NativeException
拋出裝載,定位等方面的異常
5.org.xvolks.jnative.Type
列舉和管理Jnative須要的不一樣的數據類型

(二) 如何使用

 下面以一個我在項目中使用JNative來實現的一個小例子來說解:

java 調用dll (ReaderDriver.dll 其中有三個方法), 主要功能, a.鏈接讀寫器 ;b.巡卡(讀出卡序列號);c.關閉讀寫器。

環境:

1.將JNativeCpp.dll ,拷貝到windows / system32目錄下;

2.將JNative.jar導入工程中,新建一個調用類:

代碼以下:

package ecard.sys.javadll;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

/**  *  *功能描述:java調用dll動態庫<br>  *  *建立時間:2011-7-11 上午10:32:44  *  *做者:chenab  *  *版本:V1.0  *  *版本全部:XXXXXX有限公司  *  **/ public class EcardReaderImpl {  /**   * 鏈接讀寫器   * @param port   * @return   * @throws NativeException   * @throws IllegalAccessException   */  public String ConnectionReader(int port) throws NativeException, IllegalAccessException{   JNative n = null;   try{     //1.建立JNative對象    n = new JNative("ReaderDriver.dll","ConnectReader");    //2.設置函數返回值類型    n.setRetVal(Type.INT);    //3.設置參數類型    int i=0;    n.setParameter(i++, port);    //4.執行函數    n.invoke();    //5.獲取函數返回值    return n.getRetVal();   }finally{    if(n!=null){     n.dispose();    }   }  }  /**   * 巡卡   * @return   * @throws NativeException   * @throws IllegalAccessException   */  public String ReqCardExist() throws NativeException, IllegalAccessException{   JNative n = null;   try{     //1.建立JNative對象    n = new JNative("ReaderDriver.dll","RequestCardExist");    //2.設置函數返回值類型    n.setRetVal(Type.INT);    //3.設置參數類型        //聲明指定內存空間    Pointer aa = new Pointer(MemoryBlockFactory.createMemoryBlock(100));    Pointer bb = new Pointer(MemoryBlockFactory.createMemoryBlock(100));    n.setParameter(0,aa);    n.setParameter(0,bb);       //4.執行函數    n.invoke();    StringBuffer sb = new StringBuffer();    String type = Integer.toHexString(getResult(aa.getAsByte(0)));    if("8".equals(type)){     sb.append(Integer.toHexString(getResult(aa.getAsByte(0))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(1))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(2))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(3))));    }else{     sb.append(Integer.toHexString(getResult(aa.getAsByte(0))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(1))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(2))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(3))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(4))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(5))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(6))));     sb.append(Integer.toHexString(getResult(aa.getAsByte(7))));    }    //5.獲取函數返回值    return sb.toString();   }finally{    if(n!=null){     n.dispose();    }   }  }  /**   * 反碼,高低位轉換   * @param a   * @return   */  private int getResult(int a){   if(a<0){    a=a+256;   }   return a;  }    /**   * 讀卡器蜂鳴   * @return   * @throws NativeException   * @throws IllegalAccessException   */  public String CardVoice() throws NativeException, IllegalAccessException{   JNative n = null;   try{     //1.建立JNative對象    n = new JNative("ReaderDriver.dll","CardBeep");    //設置函數返回值類型    n.setRetVal(Type.INT);    //設置參數類型        //執行函數    n.invoke();    //獲取函數返回值    return n.getRetVal();   }finally{    if(n!=null){     n.dispose();    }   }  }  /**   * 關閉讀卡器   * @return   * @throws NativeException   * @throws IllegalAccessException   */  public String CloseReader() throws NativeException, IllegalAccessException{   JNative n = null;   try{     //1.建立JNative對象    n = new JNative("ReaderDriver.dll","CloseReader");    //設置函數返回值類型    n.setRetVal(Type.INT);    //設置參數類型        //執行函數    n.invoke();    //獲取函數返回值    return n.getRetVal();   }finally{    if(n!=null){     n.dispose();    }   }  }    public static void main(String[] args)throws NativeException, IllegalAccessException {   EcardReaderImpl impl = new EcardReaderImpl();   System.out.println("鏈接讀卡器=="+impl.ConnectionReader(1));   System.out.println("蜂鳴=="+impl.ReqCardExist());   System.out.println("巡卡=="+impl.CardVoice());   System.out.println("關閉讀寫器=="+impl.CloseReader());  } }

相關文章
相關標籤/搜索