1. 程式人生 > >java使用JNA框架調用dll動態庫

java使用JNA框架調用dll動態庫

路徑 sta ... 情況下 build 官方 desc jna ace

這兩天了解了一下java調用dll動態庫的方法,總的有三種:JNI、JNA、JNative。其中JNA調用DLL是最方便的。

·JNI

技術分享圖片

·JNA

技術分享圖片

·JNative

技術分享圖片

java使用 JNI來調用dll動態庫的調用,工作量略大,一般情況下開發人員會選用JNA或JNative。

使用JNative調用DLL除了要引入jar包外還需要額外引入一個dll文件,而JNA只需要引入jar即可使用。

使用JNA框架調用DLL動態庫,步驟如下

1.導入JNA支持的jar包

添加jna-4.x.x.jar、jna-platform-4.x.x.jar到項目buildpath中(Maven項目可在中央倉庫中搜索JNA的相關依賴添加到項目中)

2.代碼調用DLL動態庫方法

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;

/**
 * JNA框架DLL動態庫讀取調用示例類
 * @ClassName: DllCall
 * @Description: 讀取調用DLL動態庫文件中的方法
 * @author: LinWenLi
 * @date: 2018年7月18日 上午10:32:16
 */
public class JNADllCall {
/** * DLL動態庫調用方法 * @Description: 讀取調用CDecl方式導出的DLL動態庫方法 * @author: LinWenLi * @date: 2018年7月18日 上午10:49:02 */ public interface CLibrary extends Library { // DLL文件默認路徑為項目根目錄,若DLL文件存放在項目外,請使用絕對路徑。(此處:(Platform.isWindows()?"msvcrt":"c")指本地動態庫msvcrt.dll) CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.
class); // 聲明將要調用的DLL中的方法,可以是多個方法(此處示例調用本地動態庫msvcrt.dll中的printf()方法) void printf(String format, Object... args); } public static void main(String[] args) { CLibrary.INSTANCE.printf("Hello, World!"); } }

註意:要調用的DLL位數要與JDK位數相同,否則無法調用。

郁悶的是,按照以上的官方測試代碼運行後,控制臺沒有報錯也沒有打印出任何東西,在多次測試無果後我將C:\Windows\System32\msvcrt.dll復制到電腦桌面,再將代碼中dll路徑改為絕對路徑,運行成功。

技術分享圖片

DLL的函數導出方式分為兩種,其中StdCall方式導出的DLL,JNA的調用代碼如下方的DLL動態庫調用方法1,Decl方式導出的DLL,調用代碼如DLL動態庫調用方法2

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;

/**
 * JNA框架DLL動態庫讀取調用示例類
 * 
 * @ClassName: DllCall
 * @Description: 讀取調用DLL動態庫文件中的方法
 * @author: LinWenLi
 * @date: 2018年7月18日 上午10:32:16
 */
public class JNADllCall {

    /**
     * DLL動態庫調用方法1
     * 
     * @Description: 讀取調用StdCall方式導出的DLL動態庫方法
     * @author: LinWenLi
     * @date: 2018年7月18日 上午10:37:58
     */
    public interface StdCallDll extends StdCallLibrary {
        // DLL文件默認路徑為項目根目錄,若DLL文件存放在項目外,請使用絕對路徑
        StdCallDll INSTANCE = (StdCallDll) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                StdCallDll.class);// 加載動態庫文件
        // 聲明將要調用的DLL中的方法(可以是多個方法)

        void printf(String format, Object... args);
    }

    /**
     * DLL動態庫調用方法2
     * 
     * @Description: 讀取調用Decl方式導出的DLL動態庫方法
     * @author: LinWenLi
     * @date: 2018年7月18日 上午10:49:02
     */
    public interface CLibrary extends Library {
        // DLL文件默認路徑為項目根目錄,若DLL文件存放在項目外,請使用絕對路徑
        CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                CLibrary.class);

        // 聲明將要調用的DLL中的方法(可以是多個方法)
        void printf(String format, Object... args);
    }

    public static void main(String[] args) {
        StdCallDll.INSTANCE.printf("Hello, World!\n");
        CLibrary.INSTANCE.printf("Hello, World\n");
    }
}

以上簡單記錄java通過JNA框架調用DLL動態庫的步驟,若需要進一步了解可參考以下博文地址:https://www.cnblogs.com/lanxuezaipiao/p/3635556.html

java使用JNA框架調用dll動態庫