[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