[ruby-list:77] Ruby extension howto (sono 3)

From: matz@... (Yukihiro Matsumoto)
Date: 1996-01-23 03:13:40 UTC
List: ruby-list #77
まつもと ゆきひろ@トヨタケーラムです.

ruby拡張モジュール作成講座の3回目です.
--
3.rubyとCとの情報共有

C言語とrubyの間で情報を共有する方法について解説します.

3.1 Cから参照できるrubyの定数

以下のrubyの定数はCのレベルから参照できる.

  TRUE
  FALSE

真偽値.FALSEはC言語でも偽とみなされる.

  Qnil

C言語から見た「nil」.

3.2 Cとrubyで共有される大域変数

Cとrubyで大域変数を使って情報を共有できます.共有できる大域
変数にはいくつかの種類があります.そのなかでもっとも良く使わ
れると思われるのはrb_define_variable()です.

  void rb_define_variable(char *name, VALUE *var)

この関数はrubyとCとで共有する大域変数を定義します.変数名が
`$'で始まらない時には自動的に追加されます.この変数の値を変
更すると自動的にrubyの対応する変数の値も変わります.

またruby側からは更新できない変数もあります.このread onlyの
変数は以下の関数で定義します.

  void rb_define_readonly_variable(char *name, VALUE *var)

これら変数の他にhookをつけた大域変数を定義できます.hook付き
の大域変数は以下の関数を用いて定義します.

  void rb_define_hooked_variable(char *name, VALUE *var,
				 VALUE (*getter)(), VALUE (*setter)())

この関数はCの関数によってhookのつけられた大域変数を定義しま
す.変数が参照された時には関数getterが,変数に値がセットされ
た時には関数setterが呼ばれる.hookを指定しない場合はgetterや
setterに0を指定する.

# getterもsetterも0ならばrb_define_variable()と同じになる.

それから,Cの関数によって実現されるrubyの大域変数を定義する
関数があります.

  void rb_define_virtual_variable(char *name,
				  VALUE (*getter)(), VALUE (*setter)())

この関数によって定義されたrubyの大域変数が参照された時には
getterが,変数に値がセットされた時にはsetterが呼ばれます.

3.3 Cのデータをrubyオブジェクトにする

Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして
取り扱いたい場合がありえます.このような場合には,Dataという
rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby
オブジェクトとして取り扱えるようになります.

Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル
化するためには,以下の関数を使います.

  VALUE data_new(void *ptr, void (*mark)(), void (*free)())

ptrはカプセル化するCの構造体へのポインタです.markはこの構造
体がrubyのオブジェクトへの参照がある時に使う関数です.そのよ
うな参照を含まない時には0を指定します.

# そのような参照は勧められません.

freeはこの構造体がもう不要になった時に呼ばれる関数です.この
関数がガーベージコレクタから呼ばれます.

通常はこのDataオブジェクトをユーザが定義したrubyクラスのイン
スタンスのインスタンス変数として格納します.そのためのマクロ
として以下のものが提供されています.

  Make_Data_Struct(obj, iv, type, mark, free, sval)

ここでobjはインスタンス変数としてDataを代入するオブジェクト
で,ivはインスタンス変数名を表すID,typeはカプセル化するCの
データの型(構造体),mark, freeは上のdata_new()の解説の通りで
す.そして,svalはtype型の変数です.

このマクロを呼び出すとsvalに構造体がmalloc()されて代入され,
かつその構造体をカプセル化したDataオブジェクトがインスタンス
変数としてobjにセットされます.

  Get_Data_Struct(objm iv, type, sval)

これらのDataの使い方はちょっと分かりにくいので,後で説明する
例題を参照してください.

In This Thread

Prev Next