“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com wrote in message news:pan.2003.04.09.11.06.37.642046@sneakemail.com…
The scripts are loaded into a stack within my c++ code
I have a c++ class ‘GMScript’ and have used swig to wrap into ruby
I use a ruby script that inherits this class
i.e.
class Test1 < Gm::GMScript
def initialize(sg,p1,p2)
super(sg,p1,p2)
@object1 = Gm::GMObjectNode.new("object1")
end
.
.
.
end
I had some trouble with extending a SWIG-class, it resulted
in a exception: nameerror.
You are using inheiritance, no problems here.
in c++ I call at start
ruby_init();
ruby_init_loadpath();
ruby_script("embedded");
rb_require("gm.so"); - swigged up wrapper lib
Look fine.
then each time a script load is requested i do the following (protect
code removed for clarity)
rb_load_protect(rb_str_new2("Test1.rb"),Qfalse,&state);
then
oClass = rb_const_get(rb_cObject, rb_intern(“Test1”));
scriptObject = rb_funcall(oClass, rb_intern(“new”),
3,sgValue,pathName,className);
Data_Get_Struct(scriptObject,GMScript,scriptPtr);
scriptPtr->obj = scriptObject;
This code could be the problem.
- bootstrapping of your swig class.
- you are not registering scriptObject, so GC won’t know that its
in usage and thus thinks it must get killed.
How does your SWIG interface file look like ???
If it includes a .H file how does it look like ???
The problem is that as I load more scripts previous scripts get freed
of by the GC. In addition, the GMObjectNode’s created within the
Scripts are also freed.
Sounds like you object is holding ruby-childen.
You will need to do rb_mark on thise.
What I want to do is only free off the Script
when the user deletes it
from the script stack and decide at this time if the GMObjectNode
should
also be deleted. I assumed that since the scriptObject is stored
within the C code the GC would not free these off (or is it because
the scriptObject is stored in GMScript superclass itself.
Wrong assumption. It depends on wheter or not you have registered
your scriptObject.
I cannot
mark the object since this is under the control of Swig. I have tried
rb_global_variable(&scriptObject)
but this does not prevent the freeing and in addition crashes the
program with an error:
How did you “try” it ???
Read my text on embedding, look at the tar.gz file 
ruby embedded into c++
Thanks for reply - i looked at your tgz last night (as well as vim and
mod_ruby.)
Thats how I’ve got this far!
Sorry for denseness but what does bootstrapping swig class mean and
why is it bad. ?
I have had a chance to look into problem further and found swig now
supports
user defined mark and free functions. I have defined these in the
interface file
but still no joy.
This is a cut down version of my code:
gm.i:
^^^^
%module gm
%{
#include “GMScript.h”
%}
%{
static void GMScript_freefunc(void *ptr)
{
cerr << “FREE\n”;
GMScript *script = (GMScript *) ptr;
delete script;
}
%}
%{
static void GMScript_markfunc(void *ptr)
{
cerr << “MARK\n”;
GMScript *script = (GMScript *) ptr;
rb_gc_mark(reinterpret_cast((script->scriptObj)));
}
%}
%markfunc GMScript “GMScript_markfunc”
%freefunc GMScript “GMScript_freefunc”
%include GMScript.h
GMScript.h
^^^^^^^^^^
#ifndef _GMSCRIPT_H
#define _GMSCRIPT_H
#include
using namespace std;
#include <ruby.h>
class GMScript
{
public:
GMScript();
~GMScript();
VALUE scriptObj;
};
#endif
GMScript.cpp
^^^^^^^^^^^^
#include “GMScript.h”
/*****************************************/
GMScript::GMScript()
{
cerr << “GMScript::GMScript\n”;
}
/*****************************************/
GMScript::~GMScript()
{
cerr << “GMScript::~GMScript\n”;
}
main.c
^^^^^^
int main()
{
GMScript *ptr = NULL;
int state = 0;
VALUE vTclass;
VALUE tObj;
vector<GMScript *> stack;
ruby_init();
ruby_script("embedded");
ruby_init_loadpath();
rb_require("gm.so");
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);
Data_Get_Struct(tObj,GMScript,ptr);
ptr->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
GMScript::GMScript
FREE
GMScript::~GMScript
GMScript::GMScript
FREE
GMScript::~GMScript
GMScript::GMScript
FREE
GMScript::~GMScript
GMScript::GMScript
MARK
GMScript::GMScript
FREE
GMScript::~GMScript
FREE
GMScript::~GMScript
GMScript::GMScript
MARK
GMScript::GMScript
MARK
FREE
GMScript::~GMScript
…
…
…
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?
Do I need to do both mark AND rb_global_variable?
Cheers in advance
Steve
···
On Tue, 08 Apr 2003 19:56:33 +0000, Steve Hart wrote: