我使用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<ruby.h>
#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 `<main>'
请帮我解决这个问题。谢谢。
答案 0 :(得分:3)
该行
VALUE method_test(VALUE y) {
应该是
VALUE method_test(VALUE self, VALUE y) {
NUM2INT(y)
抛出了错误消息,因为y
是代码中脚本的根Object
。根对象是你得到的,因为你在模块的顶级混合了你的模块。如果你已经混入了另一个类,那么你将获得该类的实例。
所有原生扩展方法都应该采用self
参数(如果您有固定数量的参数,则为第一个参数),这是他们被调用的上下文(Module
,{{1} }或Class
的实例。当您致电Class
时,这就是foo
进入扩展程序的方式。当Ruby和C ++都自动执行此操作时可能会出现这种情况(Ruby中为foo.test
,C ++中为self
):但是由于Ruby内部API,因此必须将this
显示为参数。是用C语言编写的,它不直接支持OO - 相反,self
中定义的Ruby API要求你编写和使用C函数,这些函数将当前对象的引用作为参数之一。
此外,您正在调用ruby.h
- 这是不存在的(尽管编译器可能是善意的,并且会自动强制Circle( int radius )
)。您可能希望始终使用x
个变量并使用double
和NUM2DBL(y)