C rb“类”新“实例引发”;ArgumentError:类型错误";-为什么?

C rb“类”新“实例引发”;ArgumentError:类型错误";-为什么?,c,ruby-c-extension,C,Ruby C Extension,从我的Ruby C扩展中,我想从Google SketchUp Ruby API创建一个新的Geom::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] =

从我的Ruby C扩展中,我想从Google SketchUp Ruby API创建一个新的
Geom::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>
我遇到了和同样的问题

rb\u class\u new\u instance
是在Ruby C中创建新实例的首选方法,对吗?
有人知道我为什么要打电话给新的吗?在SketchUp中如何定义该类有些奇怪?

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

SketchUp利用
Data\u Wrap\u Struct
将他们的C类与Ruby类链接起来。但他们使用了一种旧的数据分配方法,即
#新的
方法

在Ruby 1.8中,您可以使用
rb\u define\u alloc\u func()
来进行分配,而且您永远不会在
#new
上乱动。Ruby(1.6和1.8)定义了
#new
来调用
rb_class_new_instance()

由于我在SketchUp的旧样式类中使用了
rb\u class\u new\u instance()
,因此没有正确创建对象,因此分配函数被绕过,从未触发。我犯的错误来自SketchUp,而不是Ruby

因此,答案是,您可以使用
rb\u class\u new\u instance()
创建类的新实例,前提是它们没有重载
\new
方法来进行任何初始化。在Ruby 1.6之前,如果Ruby C类需要分配数据,这在Ruby C类中很常见,但从1.8开始,应该使用
rb\u define\u alloc\u func()
完成。(马茨在这里这样说:)

在本文中,您可以看到Ruby 1.6样式和1.8样式之间的差异:

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;
}