ARGENTO CUORE

 May the code be with you.

--.--.--[--] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2009.12.05[土] Ruby拡張ライブラリ作成メモ(C構造体)

拡張ライブラリ作成

ruby.hをincludeし、Ruby拡張ライブラリを作成するためのマクロ、タイプを使用できるようにする。
ruby.hは、ruby-devをインストールしなければ使えない。

作成したCソースのビルド
・extconf.rbを記述
・extconf.rbを実行しMakefileを作成
・作成されたMakefileを使用しmakeする



C構造体をRuby側で扱えるようにするには、
VALUE Data_Wrap_Struct(VALUE klass, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free, void *sval)
で構造体をラッピングして、
void Data_Get_Struct(VALUE obj, type, type *svar)
で取り出すようにする。

■Data_Get_Struct(VALUE obj, type, type *svar)の説明
obj - Rubyオブジェクト
type - 取得するデータ構造型(struct)
*svar - 取得したデータ構造型を代入するポインタ変数

Rubyオブジェクトとは、rb_define_class()などによって作られたオブジェクトを指す。
例えば、K3DVertexクラスは以下のようにして作られる。
cK3DVertex = rb_define_class_under(mKAGUYA,"K3DVertex",rb_cObject);
これは、
module KAGUYA
class K3DVertex < Object
end
end
に相当し、C言語上では、cK3DVertexがクラスのオブジェクトになる。

K3DVertexは、3DのVertex情報を収める以下のような構造体型を定義している。

typedef struct {
Vector3D *vec;
}K3DVertex;

これを例としてC構造体のデータを取得するには、

K3DVertex *v;
Data_Get_Struct(cK3DVertex, K3DVertex, v);

という形で書く。
処理内容は、Data_Get_Structの説明通り、K3DVertexクラス内のデータ型K3DVertexよりデータを取得し、vに代入する。

■クラスに構造体型を登録するには
Rubyのクラスメソッドallocateの際に実行する関数を登録するには、
rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass))
を使用する。
これを使って、構造体型をクラスに登録する。

ex)
rb_define_alloc_func(cK3DVertex, K3DVertex_s_alloc)

これで、K3DVertex_s_allocという関数がallocate時に呼ばれる。

構造体データ型K3DVertexをklassに登録するコードは以下のようにする。
static VALUE K3DVertex_s_alloc(VALUE klass){
K3DVertex *v = ALLOC(K3DVertex);
return Data_Wrap_Struct(klass,0,K3DVertex_free,v);
}
void K3DVertex_free(K3DVertex *v){
/*特殊な解放処理が必要であればここに記述*/
free(v);
}

ALLOC(TYPE)でTYPEに必要なメモリを確保し、Data_Wrap_Structで指定したクラスに対して構造体をDataでラッピングする。

Data_Wrap_Structの解放関数のところにはK3DVertex_freeと記述しているが、-1を入れれば普通の解放処理をしてくれる。特殊な解放処理をしなければならないときには、free関数を登録する。

Cの構造体型をData型にラップするという処理の流れ
・構造体型を定義(typedef struct K3DVertex)
・構造体型はオブジェクトとして扱われる->扱うクラスを作成(K3DVertexクラス)
・クラスのallocate時に、構造体型のメモリを確保し、Data_Wrap_Structを使って確保したメモリのポインタをData型にラッピングしてもらう。
・Wrap時に解放のための関数を登録する(オプション)


■取得する関数
static K3DVertex* GetK3DVertex(VALUE obj){
K3DVertex *v;
Data_Get_Struct(obj, K3DVertex, v);
return v;
}
スポンサーサイト

Comment






(編集・削除用)


管理者にだけ表示を許可

Trackback

http://ronor.blog81.fc2.com/tb.php/13-3b988b76

この記事にトラックバック(FC2Blog User)

Scala Feed

scala feed

FC2カウンター

プロフィール

RoNor

Author:RoNor
得意呪文はScalaですって言えるようになるのが夢です。
デスマーチ中、パーティメンバーの防御力を向上させたりさせなかったり。

検索フォーム

QRコード

QRコード

Copyright © 2009-2010 ARGENTO CUORE and RoNor All rights reserved.

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。