gpt4 book ai didi

c - rb_class_new_instance 引发 "ArgumentError: wrong type"- 为什么?

转载 作者:行者123 更新时间:2023-11-30 18:01:40 25 4
gpt4 key购买 nike

通过我的 Ruby C 扩展,我想从 Google SketchUp Ruby API 创建一个新的 Geom::Vector3d 实例:https://developers.google.com/sketchup/docs/ourdoc/vector3d

我最初的代码是这样的:

static inline VALUE
vector_to_sketchup( Point3d vector )
{
VALUE skp_vector, args[3];

args[0] = rb_float_new( vector.x );
args[1] = rb_float_new( vector.y );
args[2] = rb_float_new( vector.z );

skp_vector = rb_class_new_instance( 3, args, cVector3d );
}

但这引发了一个错误:

Error: #<ArgumentError: wrong type - expected Sketchup::Vector3d>

相反,我必须调用 ruby​​ new 方法 - 像这样:

static inline VALUE
vector_to_sketchup( Point3d vector )
{
VALUE skp_vector;

skp_vector = rb_funcall( cVector3d, sNew, 3,
rb_float_new( vector.x ),
rb_float_new( vector.y ),
rb_float_new( vector.z )
);

return skp_vector;
}

我遇到了同样的问题 Geom::Point3dSketchup::Color .

rb_class_new_instance 是在 Ruby C 中创建新实例的首选方法,对吗?有人知道为什么我需要调用 new 吗? SketchUp 中类的定义方式有些奇怪吗?

最佳答案

与Google SketchUp的开发者沟通后,我找到了原因。

SketchUp 使用 Data_Wrap_Struct 将其 C 类与 Ruby 类链接起来。但他们使用旧的数据分配方法 - 该方法位于 #new 方法中。

在 Ruby 1.8 中,您使用 rb_define_alloc_func() 进行分配,并且永远不会乱用 #new。 Ruby(1.6 和 1.8)定义 #new 来调用 rb_class_new_instance()

由于我在 SketchUp 的旧样式类上使用了 rb_class_new_instance() ,因此未正确创建对象,因此分配函数被绕过并且从未触发。我收到的错误来自 SketchUp,而不是 Ruby。

所以答案是,您可以使用 rb_class_new_instance() 创建类的新实例,前提是它们没有重载 #new 方法来执行任何初始化。在 Ruby 1.6 之前,如果 Ruby C 类需要分配数据,这种情况很常见,但从 1.8 开始,应该使用 rb_define_alloc_func() 来完成。 (Matz 在这里这么说:https://web.archive.org/web/20131003102349/http://www.justskins.com/forums/the-new-allocation-scheme-132572.html#post437362)

您可以在这篇文章中看到 Ruby 1.6 风格和 1.8 风格之间的差异:https://web.archive.org/web/20131003102349/http://www.justskins.com/forums/the-new-allocation-scheme-132572.html#post444948

关于c - rb_class_new_instance 引发 "ArgumentError: wrong type"- 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9668377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com