From: emilie3012@... (Steve Hart) Date: 2003-04-10T23:44:47+09:00 Subject: Re: embedding ruby with swig "Simon Strandgaard" <0bz63fz3m1qt3001@sneakemail.com> wrote in message news:... > On Wed, 09 Apr 2003 17:56:52 +0000, Steve Hart wrote: > > > > int main() > > { > > GMScript *ptr = NULL; > > int state = 0; > > VALUE vTclass; > > VALUE tObj; > > vector stack; > > Suggestion for improving your code-readability: > Move your variable-declaration down to where they are > being used for the first time. > > > > ruby_init(); > > ruby_script("embedded"); > > ruby_init_loadpath(); > > rb_require("gm.so"); > > Looks fine. > > > > for(;;) > > { > > rb_load_protect(rb_str_new2("Class.rb"),0,&state); > > vTclass = rb_const_get(rb_cObject, > > rb_intern("MyClass")); > > tObj = rb_funcall(vTclass, rb_intern("new"), 0); > > Looks fine. > The next 2 lines look interesting.. > > > Data_Get_Struct(tObj,GMScript,ptr); > > ptr->scriptObj = tObj; > > There is something odd about them.. try > > tObj = new GMScript; > tObj->scriptObj = tObj; > > > > > // save on stack > > stack.push_back(ptr); > > > > // see what it does > > rb_gc(); > > > > sleep(1); > > cerr << "\n"; > > } > > > > return 0; > > } > > > > and I get the following out put > > [snip output] > > Sorry I don't understand your output. > > > > So, the mark is called - but so is free. I did find that if I use a > > ruby array instead of vector, push tObj and call rb_global_variable on > > this array the free never gets called. This leads me to ask if the > > scriptObj returned from rb_funcall is the correct value to mark. > > If not, then how do I obtain the correct corresponding ruby VALUE for > > ptr . In fact, I need to do this to mark children held by > > GMScript::MyClass? > > I am very sleepy right now.. maybe I understand tomorrow :-) > > > > Do I need to do both mark AND rb_global_variable? > > No. They are mutual exlusive Hi Simon Thanks for the reply - sorry if I kept you up! I think I've sussed the problem and oh dear, how stupid could I be! The problem I had was that even though the mark function gets called so does free immediately afterwards. This is because i declare tObj once, pass a reference to rb_gc_register_address and then next time round the loop just overwrite it. If I change main.cpp(!) to for(;;) { rb_load_protect(rb_str_new2("Class.rb"),0,&state); VALUE vTclass = rb_const_get(rb_cObject, rb_intern("MyClass")); VALUE *tObj = (VALUE *)malloc(sizeof(VALUE)); *tObj = rb_funcall(vTclass, rb_intern("new"), 0); rb_gc_register_address(tObj); // store the value Data_Get_Struct(*tObj,GMScript,ptr); ptr->scriptObj = tObj; // see what it does cerr << "\n"; rb_gc(); sleep(1); rb_gc_unregister_address(tObj); } I'm a bit doubtful about the malloc - should I do something different here? It all works though I also had to change the mark and free functions in swig to: %{ static void GMScript_freefunc(void *ptr) { cerr << "FREE\n"; GMScript *script = static_cast(ptr); free(script->scriptObj); delete script; } %} %{ static void GMScript_markfunc(void *ptr) { cerr << "MARK\n"; GMScript *script = static_cast(ptr); rb_gc_mark(*script->scriptObj); } %} I'm also unsure regarding the static_cast. I've seen examples using static_cast,dynamic_cast,reinterpret_cast and no cast at all. I'm still unclear on one issue though. I supply a mark function for swig and sure enough this gets called now, so why do I have to register the object (tObj) on the c++ side? Cheers for the response and keep up the good work on the tutorial!