问题是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上标记两个对象中的哪一个?
>我该怎么办?我只是用rb_gc_mark标记,还是只在某些条件下才能这样做?哪个?
>我应该标记什么?标记函数只接收指向我的struct的裸指针,但rb_gc_mark函数需要VALUE.
这意味着当它们被创建时,你会想要做这样的事情:
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<>),它将带有世界值.
警告:我没有测试过任何上述代码,但它应该是方向正确的.
总结以上是内存溢出为你收集整理的ruby – Data_Wrap_Struct和销毁订单全部内容,希望文章能够帮你解决ruby – Data_Wrap_Struct和销毁订单所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)