2009年7月9日木曜日

C++によるrubyの拡張

現在研究中のプログラムをライブラリ化して簡単に使えるように ruby の binding がうまくいくかを試してみようと思った。README.EXT.ja や Programming Rubyを参考に簡単なものを作ってみたが予想外に苦労するはめになった。それは、クラスにメソッドを登録するところで、以下のようなコードでもエラーが出るのだ。

VALUE initialize(VALUE self){
return Qnil;
}
...
void Init_something(void){
....
rb_define_method(klass, "initialize", initialize, 0);
....
}


エラーメッセージ
error: invalid conversion from ‘VALUE (*)(VALUE)’ to ‘VALUE (*)(...)’


これは rb_define_method の引数の型が合わないことが原因で、reinterpret_cast を使って対処することにした。この方法が分かるまで本当に面倒だった。
#define RB_FUNC(f) reinterpret_cast<VALUE (*)(...)>(f)

void Init_something(void){
....
rb_define_method(klass, "initialize", RB_FUNC(initialize), 0);
....
}