- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我正在为物理引擎编写一个 Ruby 扩展。此物理引擎具有链接到世界 的body,因此我的Ruby 对象是World
和Body
。主体是使用 world->CreateBody
构建(在 C++ 中)并使用 world->DestroyBody
销毁。
问题在于 Ruby GC 会先于 body 破坏世界。所以,当 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 对象创建(我不能简单地 new
它)。所以它看起来像这样:
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;
}
所以我的问题是:
rb_gc_mark
做标记,还是应该只在某些条件下做标记?哪些?rb_gc_mark
函数需要一个 VALUE
。最佳答案
您应该能够注册 VALUE
的 World
as busy 与 Body
的所有 实例的生命周期相关与之相关。
这意味着当它们被创建时,你会想要做这样的事情:
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;
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<>)来承载世界 VALUE
.
警告:我没有测试过以上任何代码,但它的方向应该是正确的。
关于ruby - Data_Wrap_Struct 和销毁顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24932263/
我正在为物理引擎编写一个 Ruby 扩展。此物理引擎具有链接到世界 的body,因此我的Ruby 对象是World 和Body。主体是使用 world->CreateBody 构建(在 C++ 中)并
我正在编写一个 Ruby 扩展,我正在使用函数 Data_wrap_struct。 为了参与 Ruby 的标记和清除垃圾收集过程,我需要定义一个例程来释放我的结构,以及一个例程来标记从我的结构到其他结
这是我的精简代码,它隔离了我的问题: #include "ruby.h" #include "stdlib.h" typedef struct HandValues { double pair
我在 Ruby C 扩展中包装了一个 C 结构,但我在文档中找不到 Data_Wrap_Struct 和 TypedData_Wrap_Struct 之间的区别,这两个函数之间有什么区别? 最佳答案
我正在尝试为一个库创建一个 C 包装器,并且我构建了这段代码,它似乎与网络上的大多数示例相匹配: #include #include #include "ruby.h" #include "lps
rb_iv_get 和 rb_iv_set 对比。 Data_Wrap_Struct 用于自定义类 因此,在阅读 Ruby 扩展 API 时,我发现 Data_Wrap_Struct 可以将指针转换为
我是一名优秀的程序员,十分优秀!