Go で Mecab を使ってみた
$GOROOT/misc/cgo/ にサンプルがあったので、試してみた。
Makefile は $GOROOT/misc/cgo/stdio/Makefile を流用して、
バインド部分を書いて、make するだけ。
実際に動かしてみたい場合は、検証用のソースコードを用意して、
ファイル名が main.go なら make main のように実行すると、実行ファイルができあがる。
作ってみて気づいた点は、
- 作成したライブラリは ${GOROOT}/pkg/${GOOS}_${GOARCH} に置かれる。
- cgo で生成された .cgo3.c と .cgo4.c の関数名の頭に 0xC2 が挿入される。
- パッケージ名称に、Makefile の TARG や元ファイルの file.go が影響する。
かな。
カテゴリは Go と golang のどっちにしようかな。
Mecab バインド用ソースコード
package mecab /* #include <mecab.h> struct mecab_t {}; */ import "C" func New2(s string) *C.mecab_t { p := C.CString(s); m := C.mecab_new2(p); return m; } func SparseToStr(m *C.mecab_t, s string) string { p := C.CString(s); r := C.mecab_sparse_tostr(m, p); ret_val := C.GoString(r); return ret_val; }
Makefile
include $(GOROOT)/src/Make.$(GOARCH) TARG = mecab CGOFILES = file.go #CGO_CFLAGS = -I #CGO_LDFLAGS = CGO_LDFLAGS = -lmecab include $(GOROOT)/src/Make.pkg %: install %.go $(GC) $*.go $(LD) -o $@ $*.$O example: @export LD_LIBRARY_PATH=/usr/local/lib; \ ./main
動作検証用ソースコード
package main import "fmt" import "mecab" func main() { fmt.Printf("hello, world\n"); s := "太郎は次郎が持っている本を花子に渡した。"; m := mecab.New2(""); r := mecab.SparseToStr(m, s); fmt.Printf("result: \n%s\n", r); }
実行結果
$ make example result: 太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー は 助詞,係助詞,*,*,*,*,は,ハ,ワ 次郎 名詞,固有名詞,人名,名,*,*,次郎,ジロウ,ジロー が 助詞,格助詞,一般,*,*,*,が,ガ,ガ 持っ 動詞,自立,*,*,五段・タ行,連用タ接続,持つ,モッ,モッ て 助詞,接続助詞,*,*,*,*,て,テ,テ いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル 本 名詞,一般,*,*,*,*,本,ホン,ホン を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 花 名詞,一般,*,*,*,*,花,ハナ,ハナ 子 名詞,接尾,一般,*,*,*,子,コ,コ に 助詞,格助詞,一般,*,*,*,に,ニ,ニ 渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 。 記号,句点,*,*,*,*,。,。,。 EOS
CentOS5.4 に OpenCV 2.0 をインストールする
rpm パッケージではなく、ソースコードからコンパイルしてインストールします。
既に 2.0.0 がリリースされているので、今回はそれで。
0. 準備
以下のサイトから OpenCV のソースコードをダウンロードする。
http://sourceforge.net/projects/opencvlibrary/
画像処理で使うライブラリのパッケージをインストールする。
# yum install libpng libpng-devel # yum install libtiff libtiff-devel # yum install zlib zlib-devel
1. コンパイル & インストール
$ tar jxf OpenCV-2.0.0.tar.bz2 $ cd OpenCV-2.0.0 $ ./configure $ make # make install
Lua から C の関数をコールする - C に Lua を組み込む
Lua側から呼び出す関数名と呼び出される関数を lua_regster() で登録する。
すると、登録した名前で Lua から呼び出せるようになります。
今回は、Lua から受け取った引数の数とそれぞれの型を出力しています。
スタック操作のインデックスは 1 からなので注意。
ソースコード
#include <stdio.h> #include <stdlib.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" int lua_argument_type(lua_State *L); int main (int argc, char *argv[]) { lua_State *L; if (argc < 2) { fprintf(stderr, "usage: %s filename\n", argv[0]); exit(1); } L = luaL_newstate(); luaL_openlibs(L); // Lua側から呼び出す関数名と呼び出される関数を登録する。 lua_register(L, "argument_type", lua_argument_type); if (luaL_dofile(L, argv[1])) { fprintf(stderr, "error: %s\n", lua_tostring(L, -1)); lua_close(L); exit(1); } lua_close(L); exit(0); } int lua_argument_type(lua_State *L) { int n, i, type; // 引数の数(スタックにある要素の数)を取得する n = lua_gettop(L); printf("number of arguments: %d\n", n); for (i = 0; i < n; i++) { // インデックスの開始は 1 から type = lua_type(L, i + 1); printf(" %d) %s(%d)\n", i + 1, lua_typename(L, type), type); } return 0; }
Lua コード
t = {}; function foo (x, y) return x + y; end argument_type("a", false, 20, t, nil, foo);
実行結果
number of arguments: 6 1) string(4) 2) boolean(1) 3) number(3) 4) table(5) 5) nil(0) 6) function(6)
スタックの内容を出力する C 関数を作成する - C に Lua を組み込む
スタックの内容を一つずつ lua_type() で型を取得して、値を出力する関数を作成します。
lua_isnumber() や lua_isstring()、lua_istable() の関数やマクロを使って、if else で場合わけもできます。
引数の型がテーブルの場合、key と value の型だけを出力しています。
ソースコード
#include <stdio.h> #include <stdlib.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" int lua_argument_dump(lua_State *L); int main (int argc, char *argv[]) { lua_State *L; if (argc < 2) { fprintf(stderr, "usage: %s filename\n", argv[0]); exit(1); } L = luaL_newstate(); luaL_openlibs(L); // Lua側から呼び出す関数名と呼び出される関数を登録する。 lua_register(L, "argument_dump", lua_argument_dump); if (luaL_dofile(L, argv[1])) { fprintf(stderr, "error: %s\n", lua_tostring(L, -1)); lua_close(L); exit(1); } lua_close(L); exit(0); } int lua_argument_dump(lua_State *L) { int n, i, type; n = lua_gettop(L); for (i = 0; i < n; i++) { // インデックスの開始は 1 から type = lua_type(L, i + 1); switch(type) { case LUA_TNIL: printf(" %d) nil\n", i + 1); break; case LUA_TNUMBER: printf(" %d) %f\n", i + 1, lua_tonumber(L, i + 1)); break; case LUA_TBOOLEAN: printf(" %d) %d\n", i + 1, lua_toboolean(L, i + 1)); break; case LUA_TSTRING: printf(" %d) %s\n", i + 1, lua_tostring(L, i + 1)); break; case LUA_TTABLE: printf(" %d) %s\n", i + 1, lua_typename(L, type)); lua_pushnil(L); while (lua_next(L, i + 1) != 0) { printf(" %s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); } break; case LUA_TFUNCTION: case LUA_TUSERDATA: case LUA_TTHREAD: case LUA_TLIGHTUSERDATA: printf(" %d) %s\n", i + 1, lua_typename(L, type)); break; default: break; } } return 0; }
Lua ソース
t = { name = "foo", value = 10, }; function foo (x, y) return x + y; end argument_dump("a", false, 20, t, nil, foo);
実行結果
1) a 2) 0 3) 20.000000 4) table string - string string - number 5) nil 6) function
RubyGems をユーザ権限の環境にインストールする
rugygems をユーザ権限のディレクトリにインストールします。
わざわざ root ユーザにならなくていいし、管理が楽かなっと。
手順は以下のサイトを参考にしました。
$HOME/opt/gems に RubyGems を、
$HOME/opt/gems_repository に RubyGems のリポジトリを、インストールしています。
今回使用するユーザは hoge。
Ruby のバージョンは 1.8.5 (2006-08-25) [i386-linux]
RubyGems のバージョンは 1.3.5
1. RubyGems をダウンロードする
$ wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
2. ダウンロードしたファイルを解凍する
$ tar zxf rubygems-1.3.5.tgz
3. インストールする
$ cd rubygems-1.3.5 $ export GEM_HOME=$HOME/opt/gems_repository $ ruby setup.rb --prefix=$HOME/opt/gems RubyGems 1.3.5 installed === 1.3.5 / 2009-07-21 Bug fixes: * Fix use of prerelease gems. * Gem.bin_path no longer escapes path with spaces. Bug #25935 and #26458. Deprecation Notices: * Bulk index update is no longer supported (the code currently remains, but not the tests) * Gem::manage_gems was removed in 1.3.3. * Time::today was removed in 1.3.3. ------------------------------------------------------------------------------ RubyGems installed the following executables: /home/hoge/opt/gems/bin/gem
4. インストール後の設定
きちんとインストールされていると、$HOME/opt/gems/bin に gem があるはずです。
ただ、この状態で実行してもエラーになります。
これからパスとライブラリのパスを通していきます。
$ $HOME/opt/gems/bin/gem /home/hoge/opt/gems/bin/gem:8:in `require': no such file to load -- rubygems (LoadError) from /home/hoge/opt/gems/bin/gem:8
gem コマンドのあるパスとライブラリのあるパスを設定します。
環境変数に設定するだけだと、次にログインしたとときに反映されないので、
.bashrc に環境変数を設定します。
$ vi ~/.bashrc # configuration: rubygems export PATH=$PATH:$HOME/opt/gems/bin:$HOME/opt/gems_repository/bin export RUBYLIB=$HOME/opt/gems/lib export GEM_HOME=$HOME/opt/gems_repository $ . ~/.bashrc
パスが通っていれば、以下のコマンドを実行すると RubyGems のバージョンが表示されます。
$ gem -v 1.3.5
ためしに RSpec をインストールしてみる
RSpec をインストールして、実際にライブラリとコマンドが使えるかどうかを確認しています。
$ gem install rspec
ライブラリが使えるかを確認
以下のようなスクリプトを書いて、実行してみます。
ライブラリが require されて、エラーがでなければ OK です。
#!/usr/bin/ruby require "rubygems" require "spec" ... 省略 ...
終了
ユーザ環境の RubyGems ができました。
おしまい。
VMWare Player に CentOS5.4 をインストールしてみた
3.0 から VMWare Player でもディクスイメージを作れるようになったので、
CentOS5.4 をインストールしてみた。
インターネット越しのネットインストールは時間がかかるので、DVDイメージをダウンロードした。
ディスクに余裕があればこっちのほうがいいね。ダウンロード時間は 1h30m くらい。
パラメータはこんな感じで。30分くらいでインストールが完了。
VMWare Player 3.0 は起動が遅い感じがする。ウインドウは表示されるけれど、反応がない時間が長い。
VirtualBox3.0は起動は早かったのに。
ホストは Windows7(32bit) だけれど、今のところは問題なく動作している。