>>版權聲明:本文為原創文章,請不要拷貝轉載。
1.JNA資料
https://github.com/java-native-access/jna
這份說明中講的還是蠻細的,參數映射,指針,回調函數等等都有涉及,源碼中還有一些例子。
2.使用例子
- 引入依賴
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.3.1</version> </dependency>
- 新建接口類來加載Native庫,映射庫中方法
public interface MsvcrtLibrary extends Library { //加載動態庫 MsvcrtLibrary INSTANCE = (MsvcrtLibrary)Native.load("msvcrt"), MsvcrtLibrary.class); void printf(String format, Object... args); }
這個是文檔中的例子,它在windows下會加載了msvcrt.dll庫。
msvcrt.dll在系統庫目錄中,可見JNA會自動搜素系統庫目錄。
- 調用native方法
public class HelloWorld { public static void main(String[] args) { MsvcrtLibrary.INSTANCE.printf("Hello, World\n"); } }
3.注意事項
- 動態庫搜素加載的路徑
指定設置搜素路徑的方式:
- 可以通過設置系統屬性“jna.library.path”
- 修改系統的庫訪問環境變量
- 將庫放置在classpath下,或者放在{OS}-{ARCH}/目錄下,比如win32-x86,win32-x86-64,linux-x86-64,linux-x86,linux-amd64,darwin等。如果放在jar文件中,則會在加載時自動提取。
建議自定義的本地庫,打入jar包中,可以參考JNA.jar
- CLibrary、StdCallLibrary、Library
CLibrary支持基於*nix的操作系統,比如各種Unix的分支和Linux等。
StdCallLibrary支持windows操作系統。
使用時如果繼承了錯誤的Library基類,會報Unrecognized calling convention錯誤。所以建議都繼承於Library。
- 並發調用
JNA支持多線程並發調用。在com.sun.jna.Library接口中有說明。
4.參數映射
參數映射問題在跨語言調用中比較麻煩,好在JNA有所考慮,下面是基礎類型和字符串的對應關系。
https://github.com/java-native-access/jna/blob/master/www/Mappings.md
指針和數組可以用java的數組表示,但是java基礎類型的數組只在函數調用范圍內起作用,超出該返回則必須使用com.sun.jna.Memory和NIO direct Buffer了。
char* argv[]可以用String[]表示。
char* argv用byte[],ByteBuffer,String表示。在表示回參時,使用byte[]和ByteBuffer表示。
c的enum可以用int替換。