Hello jna

記錄下這幾天用jna3.5.0調c++寫的dll的經歷html

os:win7java

用jna調dll首先須要一個dll文件並有可調的方法,而後根據方法的名稱,參數,返回值編寫一個interfacec++

c++須要包含一個頭文件,方法須要用extern "C" __declspec(dllexport)修飾git

c與java類型的對應關係詳見https://java-native-access.github.io/jna/3.5.0/javadoc/的Marshalling/Unmarshalling (Java/Native Type Conversions)這一節github

example:windows

Hello.h數組

extern "C" __declspec(dllexport) char** hello();

Hello.cppjvm

char** hello(){
    char** result = new char*[3]
    result[0] = "123";
    result[1] = "321";
    result[2] = NULL;// 注意,數組的最後一個元素必須爲NULL
    return;
}

以上是c++源碼,打包成Hello.dll放到某個目錄下,好比這裏移動到D:\Hello\Hello.dll,注意平臺要選擇x64,不然64位jdk可能會找不到庫測試

Hello.java編碼

public interface Hello{
    String[] hello();
}

Main.java

public class Main{
    public static void main(String[] args){
        Native.setProtected(true);// 等效於jna.protected=true,這項設置會使本地方法發生異常時生成java異常,若是爲false則本地方法發生異常時會使jvm崩潰,沒法try-catch,默認false,注意此方法只適合在windows上測試時使用
        NativeLibrary.addSearchPath("Hello", "D:\\Hello");// 注意這裏參數一不帶dll後綴,參數二是文件所在的文件夾路徑而不是文件路徑
        Hello hello = (Hello) Native.loadLibrary("Hello", Hello.class);
        System.out.println(Arrays.toString(hello.hello()));
    }
}

Native.loadLibrary(String, Class);

這個方法第一個參數填加載dll的名稱,不含.dll後綴。

搜索dll的路徑是:
1)項目的根路徑
2)操做系統的全局路徑、
3)path指定的路徑。

摘自https://blog.csdn.net/jimmy609/article/details/19076557

這裏由於調用了addSearchPath方法因此不用在意這些限制,dll能夠放在任意位置

配合visual studio調試:

首先dll須要以debug模式編譯,而後以debug模式運行java,在調用本地方法以前打好斷點,在vs中選擇調試-附加到進程,選擇java的進程,進程id能夠經過ManagementFactory.getRuntimeMXBean.getName()方法看到,前面的數字就是進程id,在vs中打好斷點,放開java的斷點就能夠進來了。

另外提一句,String和char*之間會根據jna.encoding(默認utf8)轉換,而中文系統是用的GBK編碼,中文會亂碼,能夠經過手動設置jna.encoding參數解決,不過這裏推薦使用wchar_t替換char,WString替換String

相關文章
相關標籤/搜索