ruby – Data_Wrap_Struct和销毁订单
发布时间:2020-12-17 02:06:55 所属栏目:百科 来源:网络整理
导读:我正在为物理引擎编写 Ruby扩展.这个物理引擎具有链接到世界的主体,因此我的Ruby对象是World和Body.使用world- CreateBody构建一个正文(在C中)并使用world- DestroyBody进行销毁. 问题是Ruby GC在身体之前摧毁了世界.因此,当GC破坏物体时,世界不再存在,并且
我正在为物理引擎编写
Ruby扩展.这个物理引擎具有链接到世界的主体,因此我的Ruby对象是World和Body.使用world-> CreateBody构建一个正文(在C中)并使用world-> DestroyBody进行销毁.
问题是Ruby GC在身体之前摧毁了世界.因此,当GC破坏物体时,世界不再存在,并且我得到分段错误.我知道我需要为GC标记一些东西(使用rb_gc_mark),但我不知道在哪里. World类是非常标准的,它看起来像这样: 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; } Body类有点不同,因为它需要从World对象创建(我不能简单地创建它).所以它看起来像这样: 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,w); b = w->CreateBody(); DATA_PTR(self) = b; return self; } 所以我的问题是: >我应该在GC上标记两个对象中的哪一个? 解决方法
您应该能够将World of VALUE注册为与所有Body实例关联的生命周期.
这意味着当它们被创建时,你会想要做这样的事情: extern "C" VALUE static_obj_initialize(VALUE self,w); b = w->CreateBody(); DATA_PTR(self) = b; rb_gc_register_address(&world); return self; } 当Body被销毁时你想要取消注册: extern "C" void body_free(void* b) { Body* body = static_cast<Body*>(b); World* world = body->GetWorld(); world->DestroyBody(body); rb_gc_unregister_address(&world); //almost right } 但是,这并不准确,因为rb_gc_unregister_address()想要一个VALUE *.你应该能够编写一个简单的包装器(或使用std :: pair<>),它将带有世界值. 警告:我没有测试过任何上述代码,但它应该是方向正确的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |