JNAがちょい進化したようです。
年末に@ITにアップされた記事で
実は、プリミティブデータ型しか使わないAPIだけなら、JNA 3.2.0から、5行目のインターフェイスも書かず、もっと簡単に呼び出せます。詳細はJNAサイトを参照してください。
JNIより簡単にJavaとC/C++をつなぐ「JNA」とは(2/4)−@IT
とあったので参照してみたら、JNA Direct Mapping なるものが追加されていました。
以下のようなサンプルが。
import com.sun.jna.*; /** Simple example of JNA direct mapping. */ public class HelloWorld { static { Native.register(Platform.isWindows() ? "msvcrt" : "m"); } public static native double cos(double); public static native double sin(double); public static void main(String[] args) { System.out.println("cos(0)=" + cos(0)); System.out.println("sin(0)=" + sin(0)); } }
メソッド定義しなきゃいけないところは、インターフェースの代わりにnativeメソッドにして staticイニシャライザに書いたregisterメソッド内で解決しちゃうという荒技。しかもプリコンパイルもエージェントも使用せずにやってのけちゃう。registerメソッドにはクラスも指定してない。超簡便な記述に!恐ろしい。
ソースを見もせずに実装を想像してみるに、たぶんregister呼び出しの中でコールスタックを見て呼び出し元のクラスを特定してリフレクションでnativeを探し、そのシグネチャとライブラリをマッピング(これはもう以前からJNAが実現していたことだし)してるんだろうな。でも想像だけで分からないのはnativeに対するJREの挙動としてはパスに通ったネイティブライブラリを呼び出してコールするだろうから、どうやって応答しているんだろうってこと。ネイティブライブラリがあるかのようにJREをどうやって騙すんだろうか。すげーなー。