Java Native Access

Java Native Access (JNA) 是一个由社区开发的库，它使Java程序无需使用Java Native Interface即可轻松访问本地共享库。JNA的设计旨在以最少的努力以原生的方式提供本地访问，且不需要样板代码或胶水代码。 JNA库使用一个称为外部函数接口库（libffi（英语：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 < 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 Release 5.5.0. Groups.google.com. 2019-10-30 [2020-07-23]. （原始内容存档于2011-01-22）.  Default Type Mappings. jna.dev.java.net. [2011-08-02]. （原始内容存档于2014-06-01）.  asdf/cffi – armedbear. Abcl.org. [2018-12-07]. （原始内容存档于2020-07-17）.  Nutter, Charles Oliver. Java Native Access + JRuby = True POSIX. 2007-09-02 [2018-12-07]. （原始内容存档于2020-11-09）.  JNA brings native code to JRuby. infoq.com. 2007-09-05 [2010-05-22]. （原始内容存档于2020-10-26）.  Home - FMJ. Fmj-sf.net. [2018-12-07]. （原始内容存档于2020-11-23）.  vlcj. Capricasoftware.co.uk. Caprica Software Limited. [2018-10-23]. （原始内容存档于2020-11-01）.  dblock/log4jna. GitHub. [2018-10-23]. （原始内容存档于2020-09-17） （英语）.  apache/cassandra. 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. Simplify Native Code Access with JNA. 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