[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Re: embedding ruby with swig
From:       emilie3012 () netscape ! net (Steve Hart)
Date:       2003-04-10 14:44:47
[Download RAW message or body]

"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


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<GMScript *>(ptr);
        free(script->scriptObj);
        delete script;
}

%}

%{
static void GMScript_markfunc(void *ptr)
{
        cerr << "MARK\n";
        GMScript *script = static_cast<GMScript *>(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!

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic