Java中使用JNA調用其他語言編寫的動態鏈接庫

在開發中有時需要跨平臺跨語言,用Java調用其它語言編寫的動態鏈接庫,例如編譯好的dll文件,這是就需要用到JNA(Java Native Access ),JNA是建立在經典的JNI的基礎之上的一個跨平臺框架,下面簡單介紹一下在Java中如何使用JNA調用其他語言編寫dll動態鏈接庫文件。大致可以分爲一下幾步:
1、下載jna.jar包,並導入到Java項目中;
下載地址:https://github.com/twall/jna#readme
2、把要調用的dll文件拷貝到Java工程路徑下,新建一個類,實現Library接口,並在接口類中通過JNA的Native類加載dll文件,如:

EncrypStrTest instance = (EncrypStrTest)Native.loadLibrary("Dll文件的名字", 新建的接口類名.class);

3、在接口類中聲明需要在Java中調用的函數(方法),如:

public int add(int a,int b);  
public int factorial(int n);

4、完成以上幾步就可以在自己的Java類中調用dll文件中的方法了,如:

接口類名.add3,4;

下面是一個獲取exe文件版本信息的demo,採用Version進行了進一步的封裝

package com.gmi.client;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.VerRsrc;
import com.sun.jna.platform.win32.Version;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

public class GetVersionUsingJNA {
    public List<Integer> getVersion(String path){
        File fileToCheck = new File(path);
        List<Integer> list = new ArrayList<Integer>();
        int infoSize = Version.INSTANCE.GetFileVersionInfoSize(fileToCheck.getAbsolutePath(), null);
        Pointer buffer = Kernel32.INSTANCE.LocalAlloc(WinBase.LMEM_ZEROINIT, infoSize);
        try {
            Version.INSTANCE.GetFileVersionInfo(fileToCheck.getAbsolutePath(), 0, infoSize, buffer);
            IntByReference outputSize = new IntByReference();
            PointerByReference pointer = new PointerByReference();
            Version.INSTANCE.VerQueryValue(buffer, "\\", pointer, outputSize);
            VerRsrc.VS_FIXEDFILEINFO fileInfoStructure = new VerRsrc.VS_FIXEDFILEINFO(pointer.getValue());
            // file version
            list.add((int) (fileInfoStructure.dwFileVersionMS.longValue() >> 16));
            list.add((int) (fileInfoStructure.dwFileVersionMS.longValue() & 0xffff));
            list.add((int) (fileInfoStructure.dwFileVersionLS.longValue() >> 16));
            list.add((int) (fileInfoStructure.dwFileVersionLS.longValue() & 0xffff));
            // product version
            list.add((int) (fileInfoStructure.dwProductVersionMS.longValue() >> 16));
            list.add((int) (fileInfoStructure.dwProductVersionMS.longValue() & 0xffff));
            list.add((int) (fileInfoStructure.dwProductVersionLS.longValue() >> 16));
            list.add((int) (fileInfoStructure.dwProductVersionLS.longValue() & 0xffff));

        }
        finally  {
            Kernel32.INSTANCE.GlobalFree(buffer);
        }
        return list;
    }
}

windows本身提供了很多dll控件,也可以使用自己定義的dll文件。這樣我們就可以通過JNA進行本地方法的調用了,這樣大大擴展了Java程序的面。非常方便的,當然了還有其他方法,不斷學習中……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章