お世話になっております。 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]あたりに、親近感覚えました(^^;