# MeCab ライブラリ

$Id: libmecab.html,v 1.14 2003/01/26 20:00:03 taku-ku Exp $;

MeCabには, C/C++ 共用のライブラリ (mecab.h, libmecab.so/limecab.dll) があります.

## C ライブラリ仕様

C ライブラリは以下の関数を提供しています.

`mecab_t *mecab_new (int argc, char **argv)`
  mecab のインスタンスを生成します.
  引数には, C 言語の, main 関数で使用される argc, argv スタイルの引数を与えます.
  この引数は, mecab コマンドと同じ方法で処理されます.
  成功すれば, mecab_t 型のポインタが返ってきます. このポインタを通して解析 を行います. 失敗すれば NULL が返ってきます.
`mecab_t *mecab_new2 (char *arg)`
  mecab のインスタンスを生成します.
  引数には, 一つの文字列として表現したパラメータを与えます.
  成功すれば, mecab_t 型のポインタが返ってきます. このポインタを通して解析を行います.
`char *mecab_strerror (mecab_t* m)`
  エラーの内容を文字列として取得します. mecab_sparse_tostr 等で, NULL が返ってきた場合に, mecab_strerror を呼ぶことで, エラーの内容を取得できます. mecab_new,mecab_new2 のエラーは, m を NULL と指定してください.
`char *mecab_sparse_tostr (mecab_t *m, char *str)`
  解析を行います. 引数には, mecab_new で得られた mecab_t 型のポインタと,
  解析したい文を char 型のポインタ文字列として与えます.
  成功すれば, 解析後の結果が char 型のポインタとして返り, 失敗すれば, NULL が返ってきます
  戻り値のポインタが指すメモリ領域は, 呼び出し側で管理する必要はありませんが,
  mecab_sparse_tostr を呼ぶ度に上書きされます.
  また, mecab_destroy を呼ぶと解放されます.
`char *mecab_sparse_tostr2 (mecab_t *m, char *str, unsigned int len)`
  mecab_sparse_tostr とほぼ同じですが, len にて, 解析する文の長さを指定できます.
`char *mecab_sparse_tostr3 (mecab_t *m, char *istr,unsigned int ilen char *ostr,unsigned int olen)`
  mecab_sparse_tostr2 に加え, 出力用の バッファ領域 (ostr), 及びその長さ (olen) を指定できます. ostr の領域の管理は, 呼び出し側が行います. 成功すれば, 解析後の結果が char 型のポインタとして返ってきます. これは, ostr と同じになります. もし, 解析結果の長さが olen 以上になった場合は, 解析失敗とみなし, NULL を返します.
`int mecab_lock (mecab_t *m)`
  m にて指定されるインスタンスの動作を mutex を用い 排他的に lock します. マルチスレッド環境にて インスタンス m を複数のスレッドから用いる場合は, lock が必要です.
`int mecab_unlock (mecab_t *m)`
  m にて指定されるインスタンスの動作の lock を解除します.
`void mecab_destroy(mecab_t *m)`
  mecab_t 型のポインタを解放します.

## C サンプル

example/example.c

    #include <mecab.h>
    #include <stdio.h>

    int main (int argc, char **argv)
    {
       mecab_t *c;
       char p[1024] = "太郎は次郎が持っている本を花子に渡した。";
       char *r;

       c = mecab_new (argc, argv);
       if (c == NULL) {
          fprintf ("Exception:%s\n", mecab_strerror (c));
          return -1;
       }

       r = mecab_sparse_tostr(c, p);

       if (r == NULL) {
          fprintf ("Exception:%s\n", mecab_strerror (c));
          mecab_destroy(c);
          return -1;
       }

       printf ("INPUT: %s\n", p);
       printf ("RESULT:\n%s", r);

       mecab_destroy(c);

       return 0;
    }

## C++ ライブラリ仕様

C++ ライブラリは, シンボルの解決がコンパイラの実装依存になっているため, すべてのケースで正しくリンクできるとは限りません. mecab をコンパイルし た環境と同一環境で API を利用する場合は問題ないと思います. example/example2.cpp に具体例を示していますので, そちらを参照ください. C のライブラリは, C++ API を薄く wrap したものにすぎません.

## コンパイル方法

- UNIX の場合

      % cc -O2 `mecab-config --cflags` example.c -o example \
               `mecab-config --libs`

- Windows の場合

  まず, コンパイル作業を行うディレクトリに include\mecab.h, bin\libmecab.dll lib\libmecab.lib をコピーします.
  この後の作業は, 使用するコンパイラによって微妙に変わります.

  cygwin/mingw 環境の場合

      % gcc -DDLL_IMPORT -I. example.c -o example.exe libmecab.dll

  Visual Studio .NET C++の場合

      % cl -DDLL_IMPORT -I. example.c libmecab.lib

  BCC32 環境の場合

      インポートライブラリの作成
      % implib.exe /a /f libmecab.lib libmecab.dll
      コンパイル
      % bcc32 -DDLL_IMPORT -I. example.c libmecab.lib

  さらに, 以下例ように, libmecab.dll と動的 にリンクすることも可能です.
  この場合は, インポートライブラリを作成する必要はありません.

      #include <stdio.h>
      #include <windows.h>

      typedef void* (WINAPI *FPINIT)  (int, char **);
      typedef char* (WINAPI *FPERR)   (void*);
      typedef char* (WINAPI *FPPARSE) (void*, char*);
      typedef void  (WINAPI *FPDEL)   (void *);

      int main (int argc, char **argv)
      {
         char p[] = "太郎は次郎が持っている本を花子に渡した。";
         HINSTANCE hLib = LoadLibrary("libmecab.dll");

         if (hLib) {
            FPINIT  fpInit  = (FPINIT)  GetProcAddress(hLib, "mecab_new");
            FPERR   fpErr   = (FPERR)   GetProcAddress(hLib, "mecab_strerror");
            FPPARSE fpParse = (FPPARSE) GetProcAddress(hLib, "mecab_sparse_tostr");
            FPDEL   fpDel   = (FPDEL)   GetProcAddress(hLib, "mecab_destroy");

            if (fpInit && fpErr && fpParse && fpDel) {
               void *c = (void *)(*fpInit)(argc, argv);
               if (!c) {
                  fprintf (stderr, "Exception %s\n", (*fpErr)(c));
                  FreeLibrary(hLib);
                  return -1;
               }

               printf ("INPUT: %s\n", p);
               printf ("RESULT:\n%s", (char *)(*fpParse)(c, p));
               (*fpDel)(c);
            }
            FreeLibrary(hLib);
         }

         return 0;
      }

## マルチスレッドについて

MeCab は, マルチスレッド環境で使用することが可能です. 使い方は, 以下の2つの方法があります.

### 1インスタンス = 1スレッドの場合

1つのスレッドに 1インスタンスを割りあてる場合は, ユーザがとりたてて必要することはございません. 辞書は mmap (MapViewOfFile) を用いて, OS の仮想メモリ上に 割りあてられるため, 複数のインスタンスを作成しても, 多くのメモリを使用することは ありません.

### 1インスタンスを複数のスレッドからアクセスする場合

この場合は, 同期をとる必要があります. 具体的には, mecab_lock にて 1つのスレッドが使用権を取得し, 解析後に mecab_unlock を使い使用権を 開放します.

マルチスレッド (pthread) の場合の例を example/example-thread.c example/example-thread2.c に示します.

$Id: libmecab.html,v 1.14 2003/01/26 20:00:03 taku-ku Exp $;