**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通用类型的对应关系.

| C类型 | 大小 | Java类型 | Windows通用类型 |
| --- | --- | --- | --- |
| char | 8-bit integer | byte | BYTE, TCHAR |
| short | 16-bit | short | short WORD |
| wchar\_t | 16/32-bit character | char | WCHAR, TCHAR |
| int | 32-bit integer | int | DWORD |
| int | boolean value | boolean | BOOL |
| long | 32/64-bit integer | NativeLong | LONG |
| long long, \_\_int64 | 64-bit integer | long | LONGLONG |
| float | 32-bit FP | float |  |
| double | 64-bit FP | double |  |
| char\* | C string | String | LPCTSTR |
| void\* | pointer | Pointer | LPVOID, HANDLE, LPXXX |

**注意：**根据一些预处理器指令和不同的实现，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 < args.length; i++) {
 CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[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

参考链接
----

1. ↑ . jna.dev.java.net.  [2011-08-02]. （原始内容存档于2014-06-01）.
2. ↑ . Abcl.org.  [2018-12-07]. （原始内容存档于2020-07-17）.
3. ↑  Nutter, Charles Oliver.. 2007-09-02  [2018-12-07]. （原始内容存档于2020-11-09）.
4. ↑ . infoq.com. 2007-09-05  [2010-05-22]. （原始内容存档于2020-10-26）.
5. ↑ . Fmj-sf.net.  [2018-12-07]. （原始内容存档于2020-11-23）.
6. ↑ . Capricasoftware.co.uk. Caprica Software Limited.  [2018-10-23]. （原始内容存档于2020-11-01）.
7. ↑ . GitHub.  [2018-10-23]. （原始内容存档于2020-09-17） （英语）.
8. ↑ . GitHub.  [2018-12-07]. （原始内容存档于2020-12-10）.

外部链接
----

* Java Native Access Web Page （页面存档备份，存于）
* Java Native Access - Download page （页面存档备份，存于）
* Java Native Access - User Mailing List （页面存档备份，存于）
* Java Native Access:An easier way to access native code （页面存档备份，存于） by Jeff Friesen, JavaWorld.com,2008-02-05
* Protect Your Legacy Code Investment with JNA by Stephen B. Morris, Java.net,2009-05-20
* Dasgupta, Sanjay.. Java.net. 2009-09-11  [2020-07-23]. （原始内容存档于2009-11-15）.
* JNA is now a Githubber（页面存档备份，存于） by Daniel Doubrovkine, 2011-09-20
* Calling the Lotus Domino C-API with JNA （页面存档备份，存于） by Jesper Kiaer 2010-03-21