お世話になっております。 A.中村です。
On Wed, 16 Jun 1999 17:07:34 +0900
Shugo Maeda <shugo / netlab.co.jp> wrote:
> rb_ivar_set(obj, rb_intern("@foo"), val);
ソース、今朝見て、誤爆に気づきました。
オブジェクトの@data(を束縛している)Dataオブジェクトを
取り出した「後」に、モンダイのC構造体をInitializeする関数を
呼んでしまっていました。これではData(を束縛?してる)構造体を
触ろうとするたびに、その内容が破壊されてしまって当然でした(T_T)
Eventオブジェクトが内蔵する(?)mnwEvent構造体に
アクセスするための関数が、コレです。
mnwEvent*
cEvent_getData(VALUE self){
mnwEvent* s=c_getData(self, sizeof(mnwEvent), mnwEvent_Finalize);
mnwEvent_Initialize(s); //!!!!!!!!!!
return s;
}
!!!の所がそのInitialize関数です。#某GUIキットのAPIとして与えられた関数。
んで、c_getDataは、
idData=rb_intern("data");
void*
c_getData(VALUE self, size_t size, void(*free)(void*)){
if (rb_ivar_get(self, idData)==Qnil){
void* ret=ALLOC(size);
rb_ivar_set(self, idData, Data_Wrap_Struct
(rb_cData, 0, free, ret));
return ret;
}else return (void*)DATA_PTR(rb_ivar_get(self, idData));
}
です。
でもこれじゃ役不足だったんですね。正しくは例えば、
mnwEvent*
cEvent_getData(VALUE self){
mnwEvent* s=c_getData(self, sizeof(mnwEvent),
mnwEvent_Initialize, mnwEvent_Finalize);
return s;
}
という風に使えるように、Initialize関数もc_getDataに与えるように
すべきでした。
void*
c_getData(VALUE self, size_t size, void(*init)(void*), void(*free)(void*)){
if (rb_ivar_get(self, idData)==Qnil){
void* ret=ALLOC(size);
init(ret); //!!!!!!!!
rb_ivar_set(self, idData, Data_Wrap_Struct
(rb_cData, 0, free, ret));
return ret;
}else return (void*)DATA_PTR(rb_ivar_get(self, idData));
}
#と、さっき出勤途上に考えたんで試すのは今晩(^^;
しかしこの方針、xxxx_Initializeに引数が必要になったら面倒だなあ…
ああ、やっぱり多態って偉大だなあ(T_T)
#initializeとnew、finalizeとfree、の区別がオカシイ所が
#まだあるんで、それも直そうっと。
31件のほうですが(って今朝見たらまた増えてるし)、
Gtkのシグナル(messageのことかな)の話題、
特に[ruby-list:9475]あたりに、親近感覚えました(^^;