"Simon Strandgaard" <0bz63fz3m1qt3001 / sneakemail.com> wrote in message news:<pan.2003.04.10.03.26.14.705399 / sneakemail.com>... > 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<GMScript *> 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 My previous post has not appeared yet but I have a better solution now. Forget the malloc - that was silly. If I now do the following in the for loop rb_load_protect(rb_str_new2("Class.rb"),0,&state); VALUE vTclass = rb_const_get(rb_cObject, rb_intern("MyClass")); VALUE tObj = rb_funcall(vTclass, rb_intern("new"), 0); Data_Get_Struct(tObj,GMScript,ptr); ptr->scriptObj = tObj; rb_gc_register_address(&(ptr->scriptObj)); // see what it does cerr << "\n"; sleep(1); rb_gc(); Its OK and I get: GMScript::GMScript MARK GMScript::GMScript MARK MARK GMScript::GMScript MARK MARK MARK GMScript::GMScript which makes sense - each subsequent rb_funcall creates a new object and the number of marks increase accordingly. But if I omit the call to rb_gc_register_address(&(ptr->scriptObj)); I get: GMScript::GMScript FREE GMScript::~GMScript GMScript::GMScript FREE GMScript::~GMScript GMScript::GMScript The mark function in swig is never called. Why?. If I follow the code through rb_funcall --> _wrap_GMScript_allocate --> SWIG_NewClassInstance --> Data_Wrap.. --> rb_obj_call_init --> initialize() self <--- So, does this mean that the only reference held to this ruby instance is the one returned from rb_funcall and if I don't tell gc it can't call the mark. And the only reason the free can be called is because it exists in main's stack frame? Sorry for being a bit anal here, I'm just trying to get my head round what's going on. If the above is true, then great. I would be happy to call rb_gc_register_address when I create the instance, use the swig mark func for any persistant children i create within MyClass, and then call rb_gc_unregister_address when I'm done with it. I think I read somewhere that there is no harm in marking an object twice so if child objects created within GMScript are shared with other instances of GMScript and they both mark the chhildren I can select which ones I need to delete when I destroy an instance to GMScript. Am I correct here? I did read the Swig doc on this - could do with a bit more explaining here, in particular sec 20.8.5 which refers to the imaginary SWIG_RubyInstanceFor. any chance anyone might implement it!