2010年6月15日火曜日

CでRubyの拡張ライブラリを記述する

Check
http://members.jcom.home.ne.jp/mitakelp/makeext.html
なにはともあれパッケージでRubyの開発環境を整えよう。私の場合はDebian(lenny)なのでaptitude経由となります。
$sudo aptitude install ruby1.8-dev
$cd /usr/local/include

#シンボリックリンクの作成
#作成する場所はお好みで
$sudo ln -s /usr/lib/ruby/1.8/i486-linux ./ruby

追記:自分でMakefile書くわけじゃないので、シンボリックリンクの作成はいらないかもしれません。

次はCソースコードの用意。
precure.c
#include <ruby.h>

/**
 * va+vb+vcを返すだけのメソッド
 * @param va, vb, vc 足す数
 * @return va+vb+vc の答え
 */
VALUE heart_catch(VALUE self, VALUE va, VALUE vb, VALUE vc)
{
   VALUE r;
   int a, b, c, d;

   a = NUM2INT(va);
   b = NUM2INT(vb);
   c = NUM2INT(vc);

   d = a + b + c;

   r = INT2FIX(d);

   return r;
}

void Init_Precure(void)
{
   /* 初期化処理 */
   VALUE rb_cPrecure;

   rb_cPrecure = rb_define_class("Precure", rb_cObject);

   /* メソッド定義 */
   rb_define_method(rb_cPrecure, "heart_catch", heart_catch, 3);
}
コンパイルは特別なMakefileで行う。このMakefileを作るためにextconf.rb(名前は適当でいい)を作成する。
extconf.rb
require "mkmf"

#作成したいクラス名と同じ名前を指定する。
create_makefile("Precure")
Shell上で、
$ruby extconf.rb
creating Makefile
$make
cc -I. -I/usr/lib/ruby/1.8/i486-linux -I/usr/lib/ruby/1.8/i486-linux -I. -D_FILE_OFFSET_BITS=64  -fPIC -fno-strict-aliasing -g -g -O2  -fPIC   -c precure.c
cc -shared -o Precure.so precure.o -L. -L/usr/lib -L.  -rdynamic -Wl,-export-dynamic    -lruby1.8  -lpthread -ldl -lcrypt -lm   -lc
すると、Precure.soなる共有オブジェクトができているので、useprecure.rbにて
require "Precure.so"

precure = Precure.new
d = precure.heart_catch(1, 2, 3)
print d, "\n"
と記述して実行すると6という出力が得られる。

次はC/C++からRubyを呼び出す方法を勉強しよう。

0 件のコメント:

コメントを投稿