StoryEdit 開発日誌

ウェブアプリ StoryEditを作ってましたが延期。普通のブログ。

JNAではまる。Javaからepollを使いたい。

2時間ほどはまった。時間返せ。

JNAとは、Java Native Accessのことである。ネイティブなライブラリ関数をJavaから呼び出すための仕組みで、libffiを使って実装されている。

@ITページのサンプルに、以下のような構造体のバインドが載っている。
http://www.atmarkit.co.jp/fjava/special/jna/jna_3.html

public static class _Employee extends Structure {
     String id;        /*社員番号*/
     String name;    /*氏名*/
     int age;          /*年齢*/
     String sectionId; /*部署番号*/
}

非常に簡単である。私の以下のようにepollの構造体をバインドした。

        public static class EpollData extends Structure {
            Pointer ptr;
            int fd;
            int u32;
            long u64;
        }
        public static class EpollEvent extends Structure {
            int events;
            EpollData data;
        }

そして、テストで、この構造体をnewする。

  EpollEvent ev = new EpollEvent();

すると、こうだ。

  testCreateHandler: Structure class org.hogehoge$Libc$EpollEvent has unknown size (ensure all fields are public)

実際には、それぞれのフィールドにpublicが必要になる。エラーメッセージにもろ正解が書いてあるんだが、JNAはおろか、Javaさえよく理解していない私には、このメッセージに気づくまでに時間がかかった。

そして、以下のサイトをみて、メッセージの意味に気づく。
http://www.eshayne.com/jnaex/example04.html

なるほど。publicついてるね。

最終的にはこういう形に落ち着きそう。

        // epoll bindings
        public static class EpollData extends Structure {
            public Pointer ptr;
            public int fd;
            public int u32;
            public long u64;
        }
        public static class EpollEvent extends Structure {
            public static class ByValue extends EpollEvent implements Structure.ByValue  {}
            public int events;
            public EpollData data;
        }

追記:上のバインディングはまだ未完成だった。詳細は以下。
JNAではまる、その2。__attribute__((__packed__))のマッピングをする。 - StoryEdit 開発日誌