我使用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>'请帮我解决这个问题。谢谢。
发布于 2013-12-04 08:26:48
线
VALUE method_test(VALUE y) {应该是
VALUE method_test(VALUE self, VALUE y) {错误消息由NUM2INT(y)抛出,因为y是代码中脚本的根Object。根对象是您得到的,因为您在脚本的顶层混合了模块。如果您已经混合到另一个类中,则会得到该类的一个实例。
所有本机扩展方法都应该使用一个self参数(如果有固定数量的params,则为第一个参数),这是在其中调用它们的上下文( Module、Class或Class实例)。这就是当您调用foo时如何使foo.test进入扩展的方式。当Ruby和C++都自动这样做时(self在Ruby中,this在C++中),这可能看起来很奇怪:但是,有必要让self以param的形式出现,因为Ruby内部API是用C编写的,它不直接支持面向对象--相反,ruby.h中定义的Ruby希望您编写和使用引用当前对象作为参数之一的C函数。
此外,您正在调用Circle( int radius ) --它并不存在(尽管编译器可能会自动地为您强制使用x )。您可能希望在整个过程中使用double变量,并使用NUM2DBL(y)和DBL2NUM( cir->getArea() )
https://stackoverflow.com/questions/20368685
复制相似问题