JNA で java の SDL binding を書いてみた

JNA は Java Native Access の略で、JNI を使わずにネイティブコードな共有ライブラリにアクセスする方法を提供するライブラリ。
JNI みたいに Java のために C/C++ コードを書かずに済むのがいいところ。
やってみた感じとしては、C# の P/Invoke の方が解りやすいなぁと思った。
書き方は JNAerator に教わったんだけど、JNAerator はあんまり思ったようには仕事をしてくれないみたい。
何故かってこういう関数の定義があるとするよね:

extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags);

JNAerator は SDLCALL が返り値の型だと思い込んでこんな風に書いてしまう:

SDLLibrary.SDLCALL SDL_Init(int flags);

と憤慨してたんだけど、これは jnaerator-0.9.7.jar 時点での話で、jnaerator-0.9.10-SNAPSHOT-shaded.jar ではこんな感じに正常に変換されている。

int SDL_Init(int flags);

あと、JNAerator を普通に実行すると GUI がでるけど、これはあんまり使えない。
ヘッダーファイル 1 つだけなら大丈夫だけど。
構造体が多いときは、JNAerator 使ったほうがいいよマジで。すっげー捗る。
JNAerator は CUI の方が遥かに便利で、SDLInputsLibrary インターフェイスを作成するときに書いたシェルスクリプトを載せておく:

#!/bin/sh

library=/usr/lib/libSDL.so

java -jar ~/Downloads/jnaerator-0.9.10-SNAPSHOT-shaded.jar \
    -library SDLInput \
    /usr/include/SDL/SDL_joystick.h \
    /usr/include/SDL/SDL_keyboard.h \
    /usr/include/SDL/SDL_keysym.h \
    /usr/include/SDL/SDL_mouse.h \
    $library \
    -package jna.sdl.input \
    -o ~/workspace/test-sdljna2/ \
    -jar SDL_input.jar -v -runtime JNA \
    -noComp -noJar

JNAerator は CUI 方向の GUI 作れよマジで…。
とりあえず、使ってるオプションのだいたいの説明を書いてみた。だいたいあってると思う。

-library STRING
Library インターフェースが派生するインターフェースの名前。
-package STRING
生成された *.java が入るパッケージ名。
-o PATH
出力されるディレクトリ。
-jar STRING
出力する *.jar 名。 -noJar って書いてるのに出力されるのはこれ書いてるから?w
-v
verbose モード。
-runtime (JNA|JNAerator|BridJ)
普通に実行した時の「Runtime」ってコンボボックスと同じ。
JNA なら JNA だけを遣い、JNAerator なら JNAerator のライブラリも使う。
BridJ は…知らない。
-noComp
コンパイルしない。
-noJar
*.jar を出力しない。

SDL のヘッダーファイル全部読み込ませて自動生成させようとしたら、OutOfMemoryException 出たwww
なので、少しずつ自動生成してみたのが上のシェルスクリプト
それでも無いよりはマシなので、使ってみてはどうだろうか。