1. 程式人生 > >java呼叫dll檔案的幾種常見方式

java呼叫dll檔案的幾種常見方式

java呼叫動態庫需要關注的問題:

   1. 如何裝載DLL檔案,以及如何定位所要使用的方法;

   2. 資料型別如何對應;

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

   4. 如何獲取返回的值。

一. 資料型別對應關係

   Java Type       C Type
    boolean
        int
    byte
       char
   char
      wchar_t
   short
      short
    double
      double
    float
      float
   String
      char*

二. Jnative呼叫dll

   Jnative是對JNI技術進行了封裝,更加方便的讓java去呼叫DLL。

     1. 下載Jnative庫,其中包含JNative.jar, JNativeCPP.dll, JNativeCPP.so這三個包。 JNative.jar是需要匯入到Java工程的lib下, JNativeCPP.dll檔案放在jdk安裝目錄下,或者是user\System32目錄下,或者專案根目錄下。

     2. 將需要呼叫的dll動態連結庫放在SYSTEM32資料夾下,或者是專案根目錄下,否則會出現找不到dll檔案的錯誤。

     3. 載入DLL庫 : System.loadLibrary("TranferEth");  // TransferEth為需要呼叫的DLL檔案,只需要使用DLL檔案的檔名即可。

     4. 呼叫DLL入口函式 : JNative jnt = new JNative("TransferEth.dll", "Transfer_Ethernet");  // 引數1為需要呼叫的DLL檔案, 引數2為需要呼叫的方法。

     5. 設定返回引數型別 : jnt.setVal(Type.INT);

     6. 設定傳入引數 : jnt.setParameter(0, "TransferScale.ini");

     7. 執行呼叫 : jnt.invoke();

     8. 釋放資源 : jnt.dispose();

三. JNA呼叫dll

JJNA中,它提供了一個動態的C語言編寫的轉發器,可以自動實現Java和C的資料型別對映。你不再需要編寫C動態連結庫。


  
 1.  在java專案中引入jna.jar。 (當前引用的版本為3.4.0 , 之前的版本未提供釋放動態連結庫資源的方法)
 2.  定義呼叫介面, 介面方法與需要呼叫的DLL提供的外部函式一致。
     例如 : DLL檔案中提供入口函式:

     extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet_EX(char *cTransScale , int nKey);

     extern "C" __declspec(dllexport) UINT __stdcall Transfer_Ethernet(char *cTransScale );

則定義的介面類中如下:  (資料型別對應關係如上)

public interface CallMTScaleLibrary extends Library {
  
    public int Transfer_Ethernet_EX(String filename, int key);  
   
    public int Transfer_Ethernet(String filename); 
}

 3.  載入DLL檔案

String dir = path + "dllName";  // dll檔案的路徑,可以省略字尾名,dll和so字尾都可以載入

CallMTScaleLibrary scaleLibrary =  (CallMTScaleLibrary) Native.loadLibrary(dir, CallMTScaleLibrary.class);

4. 執行呼叫

  int result = scaleLibrary.Transfer_Ethernet(path + "TransferScale.ini");

5. 釋放資源

   一次呼叫完成後需要釋放掉資源,以便後續重複呼叫該資源。通過檢視jna的原始碼Native類中有私有方法dispose()可以主動釋放掉資源,可以通過反射的方式去呼叫該方法,也可以重寫該方法,從而實現釋放。

private static void  dispose(){
           NativeLibrary.disposeAll();         
           nativeLibraryPath = null;
}

  注意問題 :  1. 檔案路徑: DLL檔案最好放在專案的根目錄下,或者是system32資料夾下,必須在環境變數配置的path中。
                 2. 迴圈呼叫: 當迴圈呼叫同一個DLL檔案時,必須要釋放掉上一次的資源,否則會被佔用埠(每次呼叫都會線上程裡進行一次網路通訊)。

相關推薦

java呼叫dll方法

        前些天做單點登入,需要java呼叫dll,現在把成功經驗與大家分享。     使用Java呼叫DLL動態連結庫的方案通常有三種:JNI, Jawin, Jacob. 其中JNI(Java Native Interface)是Java語言本身提供的呼叫本地已編譯的函式庫的方法,本身具有跨平臺性

java呼叫dll檔案常見方式

java呼叫動態庫需要關注的問題:   1. 如何裝載DLL檔案,以及如何定位所要使用的方法;   2. 資料型別如何對應;   3. 如何給使用的方法傳遞引數;   4. 如何獲取返回的值。一. 資料型別對應關係   Java Type       C Type    bo

關於JAVA呼叫C++的方式和一些問題 UnsatisfiedLinkError

關於JAVA呼叫C++的幾種方式和一些問題 java呼叫c++有幾種方式,1.JNA方式,2,JNative 方式,3.JNI 方式。: 1.JNA方式 public interface MyCLibrary extends Library {

java讀取寫入檔案方式效率比較

public class ReadTxtJson {public static String readTxtFile(String FileName) throws Exception {BufferedInputStream bufferedInputStream = n

Java單例模式實現方式

開始 名稱 常量 就是 多線程開發 靜態代碼塊 浪費 ack 多線程同步 在平時的工作、學員的學習以及面試過程中,單例模式作為一種常用的設計模式,會經常被面試官問到,甚至筆試會要求學員現場默寫,下面將會就單例模式的實現思路和幾種常見的實現方式進行簡單的分享。

Java 定時任務的實現方式

java作業調度 tails 監聽器 ever 觸發 posit exist ttr 輕量級 JAVA實現定時任務的幾種方式 @(JAVA)[spring|quartz|定時器]   近期項目開發中需要動態的添加定時任務,比如在某個活動結束時,自動生成獲獎名單,導出exce

web實現資料互動的常見方式

前言       在當今社會,作為一名前端程式猿,並不是一昧的去製作靜態頁面就可以滿足滴;你說你會製作網頁,好吧,只能說你算是一個前端程式猿。但這是你作為一個程式猿最基本的能力,並不會為你進行加分;   我們都明白,要想提高競爭力,提高自己的技能是十灰重要的。前後臺的資

結構體定義的常見方式

大家都知道若struct後面接的是名字,則其為該結構體的名稱。 下面給出六種結構體定義,其中第一種是最基本的結構體定義,其定義了一個結構體A。 struct A //第一種 { int a; }; 第二種則是在定義了一個結構體

java呼叫webservice介面 方法

webservice的 釋出一般都是使用WSDL(web service descriptive language)檔案的樣式來發布的,在WSDL檔案裡面,包含這個webservice暴露在外面可供使用的介面。今天搜尋到了非常好的 webservice provide

python 呼叫elasticsearch的不同方式

from elasticsearch import Elasticsearch from elasticsearch_dsl import Search,Q,scan es = Elasticsearc

C#呼叫DLL方法,包括C#呼叫C\C++\C#DLL

C# 語言有很多優點,越來越多的人開始使用它來程式設計。但是,C#還有一些不足,如對不少的底層操作是無能為力的,只能通過呼叫Win32 DLL 或C++等編寫的DLL;另外,一般認為C#程式的保密性不夠強,因為它容易被Reflector 反編譯而得到部分原始碼,所以需要使用混合程式設計加強C#程式的保密性,而

NI LabWindows CVI 中呼叫 DLL方法

        這幾日上網發現CVI的討論者多了,也發現有很多CVI友們提出了一些困惑,比如用CVI載入別的程式語言寫的DLL時遇到的無法使用的問題。         首先是   extern "C",CVI中無法載入有此類宣告的DLL(有一些人發表的關於CVI載入DLL的文章中居然說必需有extern

C# 實現AOP 的常見方式

AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的中統一處理業務邏輯的一種技術,比較常見的場景是:日誌記錄,錯誤捕獲、效能監控等 AOP的本質是通過代理物件來間接執行真實物件,在代理類中

Java——基於JDK的加密方式

主要包括base64,AES,RSA,SHA和MD5等加密方式 未使用任何第三方工具,直接執行main方法即可 import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import jav

php使用redis的常見方式和用法

query email order lec 循環 簡單的 ews count 調用 一、簡單的字符串緩存 比如針對一些sql查詢較慢,更新不頻繁的數據進行緩存。 <?php $redis = new Redis(); $redis->connec

java呼叫dll方式

Java呼叫DLL有多種方式,常用的方式有JNative、JNA、JNI等。 JNative方式呼叫dll JNative是一種能夠使Java語言使呼叫DLL的一種技術,對JNI進行了封裝,可能有些讀

Java常見的編碼方式

計算 是把 oca java 編碼 不同 sta 換上 基礎上 examples 幾種常見的編碼格式 為什麽要編碼 不知道大家有沒有想過一個問題,那就是為什麽要編碼?我們能不能不編碼?要回答這個問題必須要回到計算機是如何表示我們人類能夠理解的符號的,這些符號也就是我們人類

c#中呼叫dll時報無法載入模組的常見原因

不說廢話,直接說原因: 用c#寫的a.exe程式碼: static void Main(string[] args) { int i = doit(); Console.WriteLine

Java常見的編碼方式

幾種常見的編碼格式  為什麼要編碼  不知道大家有沒有想過一個問題,那就是為什麼要編碼?我們能不能不編碼?要回答這個問題必須要回到計算機是如何表示我們人類能夠理解的符號的,這些符號也就是我們人類使用的語言。由於人類的語言有太多,因而表示這些語言的符號太多,無法用計算機中一個基本的

C++檔案讀寫之獲取檔案大小的常見方式

對檔案操作時有時獲得檔案的大小時必要的.下面是獲得其大小小的較簡單方法. #include<io.h> //C語言標頭檔案 #include<iostream> //for s