Java Native Access

**Java Native Access (JNA)** とは、JavaプログラムがJava Native Interfaceを用いずにネイティブの共有ライブラリにアクセスする方法を提供するライブラリである。JNA は最小限の作業でネイティブコードにアクセスできることを目指して設計されており、決まりきったアクセスコードを書いたりグルーコードの生成を行ったりせず、ネイティブコードへ正しく簡単にアクセスすることを最優先としている（ただし、性能にも注意が払われている）。JNAライブラリはネイティブコードを呼び出すためにlibffiを用いており、名前を指定してライブラリをロードするネイティブの関数を用いて、目的のライブラリ関数の関数ポインタを取得する。ネイティブコードにアクセスする過程で静的なバインディング、ヘッダファイル、またコンパイルは必要ない。アプリケーションの開発者はJavaのインターフェイスを用いて対象のネイティブライブラリの関数や構造体を記述する。これによって、JNIコードを記述しビルドする大きな労力をかけずにきわめて簡単にネイティブプラットフォームの機能を利用することができる。

## JNAの採用例
*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プラットフォームで動作する。


```java
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ライブラリをロードし、標準API*[[:en:mkdir|mkdir]]*を呼び出す。

**注:** 下記のコードはPOSIX環境で動作する。


```java
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");
    }
}
```


下記のプログラムは**[[:en:Kernel32.dll|Kernel32.dll]]**をロードし、*[[ビープ音|Beep]]*と*[[:en:Sleep (operating system)|Sleep]]*関数を呼び出す。

**注:** 下記のコードは Windows でのみ動作する。

```java
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);
    }
}
```


## 参考文献

## 関連項目
*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++などから自動生成するソフトウェア