Tobias Peters <tpeters / invalid.uni-oldenburg.de> wrote in message news:<Pine.LNX.4.44.0304161308490.12480-100000 / localhost.localdomain>...
> On 15 Apr 2003, Steve Hart wrote:
> > OK Here is an example
> > 
> > main()
> > {
> > 	ruby_init();
> > 	etc
> > 
> > 	test()
> > 	rb_gc();
> > }
> > 
> > void test()
> > {
> > 	VALUE v = create me a ruby obj i dont care how
> > }
> > 
> > So what happens to v?
> 
> v is a C variable on the stack and is of course removed when test() 
> returns.
> 
> I think you rather wanted to ask: "What happens to the ruby object pointed 
> to by v?"
> 
> Basically, 2 things happen:
> 1) When test returns, this object becomes _inaccessible_ for your code, 
> since there is no VALUE left that points to it.
> 2) The rb_gc() call will most likely delete the object (but no 100% 
> guarantee for that) (this uncertainty is caused by ruby's GC algorithm, 
> not by uncertainty of my mind)
> 
> You should now answer the question: Why would you want the object to stay 
> in memory after you lost any means of accessing it?
> 
> > 
> > or
> > 
> > main()
> > {
> > 
> > 	VALUE 	v;
> > 
> > 	ruby_init();
> > 	etc
> > 
> > 	test(&v)
> > 	rb_gc();
> > 
> > 	do some stuff that uses v
> > }
> > 
> > void test(
> > VALUE *v)
> > {
> > 	*v = create me a ruby obj i dont care how
> > }
> 
> After looking at ruby_init() and Init_stack(), I can tell that you've
> really found a problem here. But if you rewrite it as
> 
> > main()
> > {
> > 	ruby_init();
>      do_stuff()
> > }
>  do_stuff()
> > {
> > 	VALUE 	v;
> >
> > 	etc
> > 
> > 	test(&v)
> > 	rb_gc();
> > 
> > 	do some stuff that uses v
> > }
> 
> it will work fine and not delete the ruby object as long as v is on the 
> stack 
> 
>    T

Thanks v much for reply. However, Mauricio (prev reply) says v
definitly gets GC'd whilst you say it may not - which is correct?. I
guess the example is a bit banal so a slightly more intersting case
(and more relevant to me!)
{not necessarily syntactically correct}

ruby class inheriting swigged up cpp class:

class MyClass1 < MyModule::MyCPPBaseClass
   def initialize
      super

      @obj = self.createObjNode("obj1")

   end
end

swigged up cpp classes:

class ObjNode
{
public:
   ObjNode(string name){};
   ~ObjNode(){};

   string name;
};

class MyCPPBaseClass
{
public:
   static std::list<ObjNode *> objList;

   MyCPPBaseClass();
   ~MyCPPBaseClass();

   ObjNode   *createObjNode(string objName);

   VALUE  *scriptObj;
};

MyCPPBaseClass::MyCPPBaseClass()
{
}

MyCPPBaseClass::~MyCPPBaseClass()
{
   // will this work???
   obj = get ref to obj from std::list
   rb_gc_unregister_address(&obj);
}

ObjNode *MyCPPBaseClass::createObjNode(string objName)
{
   ObjNode                      *obj = NULL;
   list<ObjNode *>::iterator    result;

   result = find(MyCPPBaseClass::objList.begin(),
                 MyCPPBaseClass::objList.end(),
                 objName);

   if(result == MyCPPBaseClass::objList.end())
   {
      obj = new ObjNode(objName);
      MyCPPBaseClass::objList.push_back(obj);

      // do I need to do this???
      rb_gc_register_address(&obj);

      obj->v = rb_ary_new2();
   }
   else
   {
      obj = (ObjNode *)(*result);
   }

   return(obj);
}

vector<MyCPPBaseClass *> stack;

main()
{
   MyCPPBaseClass       *ptr = NULL;

   ruby_init();
   ruby_script("embedded");
   ruby_init_loadpath();

   // require swigged up dso
   rb_require("gm.so");

   // Methods from Simon's tutorial
   RUBY_CPP::Load("MyClass.rb");
   VALUE tObj = RUBY_CPP::New("MyClass",0);

   Data_Get_Struct(tObj,MyCPPBaseClass,ptr);
   ptr->scriptObj = tObj;
   
   // save on stack
   stack.push_back(ptr);

   // do I need to do this
   rb_gc_register_address(&(ptr->scriptObj));

   do some stuff - add more scripts to stack - run methods in scripts

   now need to get rid of scripts and objects

   
   rb_gc_unregister_address(&(ptr->scriptObj));
   
   // destructor for scriptObj gets called (above) ???
   rb_gc();

}

Sorry, this started out to be simple example but, by it's nature, it
gets complicated.
You see, I load ruby scripts from a 'menu' of ruby scripts in c++/Qt.
These scripts may share ObjNode's (hence the need to check if the obj
exists in createObjNode)
SWIG uses the Data_Wrap_Struct to handle ruby<=>cpp.I can use the mark
and free functions to handle obj->v but what about obj and what about
tObj?. Should I use rb_gc_register_address to let GC it's busy and
then use rb_gc_unregister_address
to free them off when the stack is cleared as I indicate above. It
would be great if this were tha case cause I've written most of the
code and it 'seems' to work - so far! I'm still debugging :-)
Or, perhaps there is a neater way of doing this?.
I guess that the point here is 2 fold 
1) to illicit answers for simons tutorial
2) confirm (definatively) that what I'm doing is correct

Thanks in advance for help and thanks for help so far
Steve