Java Native Access

Java Native Access (JNA) とは、JavaプログラムがJava Native Interfaceを用いずにネイティブの共有ライブラリにアクセスする方法を提供するライブラリである。JNA は最小限の作業でネイティブコードにアクセスできることを目指して設計されており、決まりきったアクセスコードを書いたりグルーコードの生成を行ったりせず、ネイティブコードへ正しく簡単にアクセスすることを最優先としている（ただし、性能にも注意が払われている）。JNAライブラリはネイティブコードを呼び出すためにlibffiを用いており、名前を指定してライブラリをロードするネイティブの関数を用いて、目的のライブラリ関数の関数ポインタを取得する。ネイティブコードにアクセスする過程で静的なバインディング、ヘッダファイル、またコンパイルは必要ない。アプリケーションの開発者はJavaのインターフェイスを用いて対象のネイティブライブラリの関数や構造体を記述する。これによって、JNIコードを記述しビルドする大きな労力をかけずにきわめて簡単にネイティブプラットフォームの機能を利用することができる。 JRuby - JNAをPOSIX機能の提供に使用 Freedom for Media in Java (FMJ) IntelliJ IDEA - JetBrains社の統合開発環境 SVNKit - Pure JavaによるSubversionクライアントライブラリ Videolan - JavaによるマルチメディアライブラリVLCJに使用 JNAライブラリがサポートするJavaとネイティブコードの割り当てを下表に示す。 下記のプログラムはプラットフォームの標準Cライブラリをロードし、printf関数を呼び出す。 注: 以下のコードはWindows、Linux / UNIX / macOSプラットフォームで動作する。 import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; /** Library の宣言と使用法の簡単な例 */ 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ライブラリをロードし、標準APImkdirを呼び出す。 注: 下記のコードはPOSIX環境で動作する。 import com.sun.jna.Library; import com.sun.jna.Native; /** POSIXライブラリの宣言と使用法の例 */ public class PosixExample { public interface POSIX extends Library { POSIX INSTANCE = (POSIX) Native.loadLibrary("c", POSIX.class); int chmod(String filename, int mode); int chown(String filename, int user, int group); int rename(String oldpath, String newpath); int kill(int pid, int signal); int link(String oldpath, String newpath); int mkdir(String path, int mode); int rmdir(String path); } public static void main(String[] args) { POSIX posix = POSIX.INSTANCE; 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; /** MS-Windows の Library の宣言と使用法の例 */ public class BeepExample { public interface Kernel32 extends Library { Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); boolean Beep(int dwFreq, int dwDuration); void Sleep(int dwMilliseconds); } public static void main(String[] args) { Kernel32 kernel32 = Kernel32.INSTANCE; kernel32.Beep(698, 500); kernel32.Sleep(500); kernel32.Beep(698, 500); } } ^ “Releases - java-native-access/jna”. GitHub (2020年7月14日). 2020年7月26日閲覧。 ^ Bläsing, Matthias (2020年7月14日). “Release 5.6.0”. Groups.google.com. 2020年7月26日閲覧。 ^ Java Native Access + JRuby = True POSIX ^ JNA brings native code to JRuby ^ Freedom for Media in Java ^ jna/www/Mappings.md at master · twall/jna Java Native Interface P/Invoke libffi(外部関数インターフェイスライブラリ) Java Native Access Web Page Java Native Access:An easier way to access native code By Jeff Friesen, JavaWorld.com, 2008年5月2日 Protect Your Legacy Code Investment with JNA by Stephen B. Morris, Java.net, 2009年5月20日 JNAerator - JNAなどで使うグルーインターフェイスをC/C++などから自動生成するソフトウェア