Java Native Access

Java Native Access (JNA) 是一個由社區開發的庫，它使Java程序無需使用Java Native Interface即可輕鬆訪問本地共享庫。JNA的設計旨在以最少的努力以原生的方式提供本地訪問，且不需要樣板代碼或膠水代碼。

**結構**
JNA庫使用一個稱為外部函數接口庫（libffi）的小型本機庫來動態調用本機代碼。JNA庫使用本地函數，允許代碼按名稱加載庫並檢索指向該庫中函數的指針，使用libffi庫來調用它，而無需靜態綁定，頭文件或任何編譯。開發人員使用Java interface描述目標本機庫中的函數和結構（struct）。這使得利用平臺功能非常容易，而避免了配置或構建JNI的高開銷。
JNA支持在macOS，Microsoft Windows，FreeBSD / OpenBSD，Solaris，GNU/Linux，AIX，Windows Mobile和Android上構建和測試。經過適當調整和重編譯，可以使其在大多數能夠運行Java的平臺上運行。

**類型對應**
這個表格顯示了JNA所支持的類型與java類型，Windows通用類型的對應關係.
注意：根據一些預處理器指令和不同的實現，TCHAR可能為char或wchar_t。LPCTSTR也是一樣的。

**數據結構的內存字節對齊**
JNA沒有規定內存字節的對齊方式。JNA默認為遵循OS平臺的設置，但也可以自定義對齊方式。如果本機庫的文檔中未提供關於內存對齊的詳細信息，則必須通過反覆試驗確定正確的對齊方式。

**示例**
下面這個例子展示了JNA如何加載C標準庫並使用其中的printf函數。
注意: 這個例子是跨平臺的，這意味著它可以在 Windows / GNU+Linux / Unix / macOS 運行，並得到完全相同的結果。
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
/** 這個例子展示了JNA的一個用法 */
public class HelloWorld {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary(
(Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
void printf(String format, Object... args);
}
public static void main(String args) {
CLibrary.INSTANCE.printf("Hello, World\n");
for (int i = 0; i 
下面這個例子使用了C POSIX庫並調用其中的mkdir函數。
注意: 這個例子在POSIX兼容的系統中是跨平臺的，這意味著它可以在所有POSIX兼容系統中運行並獲得相同結果，但它無法在大多數Windows系統上運行。
import com.sun.jna.Library;
import com.sun.jna.Native;
/** Simple example of native C POSIX library declaration and usage. */
public class ExampleOfPOSIX {
public interface POSIX extends Library {
	    public int chmod(String filename, int mode);
	    public int chown(String filename, int user, int group);
	    public int rename(String oldpath, String newpath);
	    public int kill(int pid, int signal);
	    public int link(String oldpath, String newpath);
	    public int mkdir(String path, int mode);
	    public int rmdir(String path);
}
public static void main(String args) {
POSIX posix = (POSIX) Native.loadLibrary("c", POSIX.class);
	    posix.mkdir("/tmp/newdir", 0777);
	    posix.rename("/tmp/newdir","/tmp/renamedir");
}
}
下面這個例子加載了Kernel32.dll並調用了其中的Beep和Sleep函數。
注意: 這個例子只能在Windows下運行。 
import com.sun.jna.Library;
import com.sun.jna.Native;
/** 這是JNA調用Windows dll的一個例子 */
public class BeepExample {
public interface Kernel32 extends Library {
// FREQUENCY可以為 37 和 32767間任意一整數
// DURATION 的單位為毫秒
public boolean Beep(int FREQUENCY, int DURATION);
public void Sleep(int DURATION);
}
public static void main(String args) {
	    Kernel32 lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
	    lib.Beep(698, 500);
	    lib.Sleep(500);
	    lib.Beep(698, 500);
}
}

**用處**
JNA被用於下列項目中：- Armed Bear Common Lisp, 使用JNA實現CFFI。- JRuby,使用JNA實現 POSIX 相關功能。- Freedom for Media in Java (FMJ)。
*JetBrains的IntelliJ IDEA。- OpenSearchServer,一個開源搜索引擎。
*SVNKit, 一個純Java的Java Subversion client庫 ，通過JNA實現相關功能。
*VLC media player, 在vlcj庫中使用。- Cyberduck 適用於FTP, SFTP, WebDAV, Cloud Files & Amazon S3的瀏覽器。- Log4j,附加日誌庫。- Hudson 和· Jenkins，持續集成服務器。- Webdriver。- YAJSW (Yet Another Java Service Wrapper)。- Cassandra, 來自 Apache Software Foundation 的開源分佈數據庫，使用JNA。

**另見**
 P/Invoke- SWIG

**參考鏈接**

**外部鏈接**
  Java Native Access Web Page date=20210118184033 -  Java Native Access - Download page date=20210118184033 -  Java Native Access - User Mailing List date=20121110152126 -  Java Native Access:An easier way to access native code date=20130512133418  by Jeff Friesen, JavaWorld.com,2008-02-05-  Protect Your Legacy Code Investment with JNA by Stephen B. Morris, Java.net,2009-05-20
*dead-url=no-  JNA is now a Githubberdate=20150524105539  by Daniel Doubrovkine, 2011-09-20-  Calling the Lotus Domino C-API with JNA date=20200717185326  by Jesper Kiaer 2010-03-21