2010年6月15日火曜日

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

http://members.jcom.home.ne.jp/mitakelp/makeext.html
なにはともあれパッケージでRubyの開発環境を整えよう。私の場合はDebian(lenny)なのでaptitude経由となります。
1$sudo aptitude install ruby1.8-dev
2$cd /usr/local/include
3 
4#シンボリックリンクの作成
5#作成する場所はお好みで
6$sudo ln -s /usr/lib/ruby/1.8/i486-linux ./ruby

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

次はCソースコードの用意。
precure.c
01#include <ruby.h>
02 
03/**
04 * va+vb+vcを返すだけのメソッド
05 * @param va, vb, vc 足す数
06 * @return va+vb+vc の答え
07 */
08VALUE heart_catch(VALUE self, VALUE va, VALUE vb, VALUE vc)
09{
10   VALUE r;
11   int a, b, c, d;
12 
13   a = NUM2INT(va);
14   b = NUM2INT(vb);
15   c = NUM2INT(vc);
16 
17   d = a + b + c;
18 
19   r = INT2FIX(d);
20 
21   return r;
22}
23 
24void Init_Precure(void)
25{
26   /* 初期化処理 */
27   VALUE rb_cPrecure;
28 
29   rb_cPrecure = rb_define_class("Precure", rb_cObject);
30 
31   /* メソッド定義 */
32   rb_define_method(rb_cPrecure, "heart_catch", heart_catch, 3);
33}
コンパイルは特別なMakefileで行う。このMakefileを作るためにextconf.rb(名前は適当でいい)を作成する。
extconf.rb
1require "mkmf"
2 
3#作成したいクラス名と同じ名前を指定する。
4create_makefile("Precure")
Shell上で、
1$ruby extconf.rb
2creating Makefile
3$make
4cc -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
5cc -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にて
1require "Precure.so"
2 
3precure = Precure.new
4d = precure.heart_catch(1, 2, 3)
5print d, "\n"
と記述して実行すると6という出力が得られる。

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

0 件のコメント:

コメントを投稿