MeCabをJNIから利用する

MeCabの 各言語のバインディングは Swing経由で利用できるのだが、なぜか Java版がうまく動かなかったので、他のバインディングを探したところ

http://code.google.com/p/cmecab-java/

があった。ただ品詞IDが取れなかったので、それを取れるようにソースを修正した。

cmecab-java/jni/net_moraleboost_mecab_Node.h

+ JNIEXPORT jlong JNICALL Java_net_moraleboost_mecab_Node__1postid
+  (JNIEnv *, jclass, jlong);

cmecab-java/jni/mecab.cpp

JNIEXPORT jint JNICALL
Java_net_moraleboost_mecab_Node__1posid(
    JNIEnv* env,
    jclass clazz,
    jlong hdl
    )
{
    DECLARE_CLASS(oomError, env, CLASS_OUT_OF_MEMORY_ERROR, 0);
    DECLARE_CLASS(mecabException, env, CLASS_MECAB_EXCEPTION, 0);

    try {
        const MeCab::Node* node = hdl2node(hdl);
        return node->posid;
    } catch (...) {
        env->ThrowNew(mecabException, "Unknown error.");
    }

    return 0;
}

cmecab-java/src/net/moraleboost/mecab/Node.java

+  public int posid()
+  {
+      if (prevHandle == 0) {
+          return 0;
+      } else {
+          return _posid(prevHandle);
+      }
+  }
+  private static native int _posid(long hdl);

    while (node.hasNext()) {
        System.out.println(node.posid());
    }

な感じで使える。