I am writing a Ruby extension for a physical engine. This physics engine has bodies that are connected to the world , which is why my objects are Ruby Worldand Body. The body is built (in C ++) with world->CreateBodyand destroyed with world->DestroyBody.
The problem is that Ruby GC destroys the world in front of bodies. So, when the GC destroys bodies, the world no longer exists, and I get a segmentation error. I know that I need to point out something for the GC (using rb_gc_mark), but I don't know where.
The class is Worldpretty standard, it looks like this:
extern "C" void world_free(void *w)
{
static_cast<World*>(w)->~World();
ruby_xfree(w);
}
extern "C" void world_mark(void *w)
{
}
extern "C" VALUE world_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, world_mark, world_free, ruby_xmalloc(sizeof(World)));
}
extern "C" VALUE world_initialize(VALUE self)
{
World* w;
Data_Get_Struct(self, World, w);
new (w) World();
return self;
}
The class is Bodyslightly different, since it must be created from a World object (I cannot just have newit). So it looks like this:
extern "C" void body_free(void* b)
{
Body* body = static_cast<Body*>(b);
World* world = body->GetWorld();
world->DestroyBody(body);
}
extern "C" void body_mark(void* b)
{
}
extern "C" VALUE body_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, body_mark, body_free, 0);
}
extern "C" VALUE static_obj_initialize(VALUE self, VALUE world)
{
Body* b;
World* w;
Data_Get_Struct(self, Body, b);
Data_Get_Struct(world, World, w);
b = w->CreateBody();
DATA_PTR(self) = b;
return self;
}
So my questions are:
- GC?
- ?
rb_gc_mark, ? ? - ? ,
rb_gc_mark VALUE.