创建ruby C ++扩展

我使用C ++类创建了一个示例ruby扩展。 当我没有解析值时,它工作正常。 但是当我解析参数时它显示错误。 这是我的代码。

C ++头文件

#ifndef CIRCLE_H_ #define CIRCLE_H_ class Circle { public: Circle(float radius):_radius(radius) {} float getArea() { return 3.14159 * _radius * _radius; } private: float _radius; }; 

CPP文件。

  #include #include"Circle.h" VALUE method_test(VALUE y){ double x= NUM2DBL(y); Circle *cir= new Circle(x); return DBL2NUM(cir->getArea()); } extern "C" void Init_Test(){ VALUE lemon = rb_define_module("Test"); rb_define_method(lemon, "test", (VALUE(*)(ANYARGS))method_test,1); } 

extconf.rb

  require 'mkmf' have_library( 'stdc++' ); $CFLAGS << " -Wall" create_makefile( 'Test' ); 

run.rb

  require 'rubygems' require 'Test' include Test puts test(7) 

当我执行run.rb时,它显示一个错误。

  run.rb:7:in `test': can't convert Object into Integer (TypeError) from run.rb:7:in `' 

请帮我解决这个问题。 谢谢。

这条线

 VALUE method_test(VALUE y) { 

应该

 VALUE method_test(VALUE self, VALUE y) { 

NUM2INT(y)抛出错误消息,因为y是代码中脚本的根Object 。 根对象就是你得到的,因为你在你的模块中混合了脚本的顶层。 如果你已经混入了另一个类,那么你将获得该类的实例。

所有本机扩展方法都应该使用一个self参数(如果你有固定数量的params,则为第一个),这是它们被调用的上下文( ModuleClassClass实例)。 当你调用foo.test时,你是如何进入扩展的。 当Ruby和C ++都自动执行此操作时,这可能看起来很奇怪(在Ruby中selfthis在C ++中):然而,由于Ruby内部API是用C语言编写的,因此必须将self作为参数出现,而C语言不直接支持OO -相反, ruby.h定义的Ruby API ruby.h您编写和使用C函数,这些函数将对当前对象的引用作为其中一个参数。

此外,您正在调用Circle( int radius ) – 这是不存在的(尽管编译器可能是善意的并且会自动强制x )。 您可能希望始终使用double变量并使用NUM2DBL(y)DBL2NUM( cir->getArea() )