创建ruby C ++扩展 [英] creating ruby C++ extension
问题描述
我使用C ++类创建了一个示例ruby扩展。它工作正常,当我没有解析的价值。但是当我解析参数它显示一个错误。这是我的代码。
C ++头文件
#ifndef CIRCLE_H_
#define CIRCLE_H_
class Circle {
public:
Circle(float radius):_ radius(radius){}
float getArea 3.14159 * _radius * _radius; }
private:
float _radius;
};
CPP档案。
#include< ruby.h>
#includeCircle.h
VALUE method_test(VALUE y){
double x = NUM2DBL(y);
Circle * cir = new Circle(x);
return DBL2NUM(cir-> getArea());
}
externCvoid 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'
要求'Test'
包括测试
puts test(7)
当我执行run.rb时会显示错误。
run.rb:7:in`test':无法将对象转换为Integer(TypeError)
from run.rb:7:in`& $ b请帮我解决这个问题。谢谢。
解决方案行
VALUE method_test(VALUE y){
应为
VALUE method_test(VALUE self,VALUE y){
NUM2INT(y)
引发错误消息,因为y
是根Object
。根对象是你得到的,因为你在模块中混合在脚本的顶层。如果你混入了另一个类,你会得到一个类的实例。
所有本机扩展方法都需要一个
self
参数(如果有固定数量的参数,是它们被调用的上下文(模块
,类
或类
)。当你调用foo.test
时,它是如何让foo
当Ruby和C ++自动完成这一操作时,这可能看起来很奇怪(在C ++中,self
,而在C ++中this
有必要使self
显示为param,因为Ruby内部API是用C语言编写的,它不直接支持OO,而是在ruby.h 希望您编写并使用将当前对象的引用作为参数之一的C函数。
正在调用
Circle(int radius)
- 它不存在(虽然编译器可能是kind和coercex
为你自动)。您可能想要使用double
变量并使用NUM2DBL(y)
和DBL2NUM - > getArea())
I created a sample ruby extension using C++ class. it works fine when i did not parse the value. but when i parse parameter it show an error. here is my code.
C++ header file
#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 file.
#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)
when i execute run.rb it shows an error.
run.rb:7:in `test': can't convert Object into Integer (TypeError) from run.rb:7:in `<main>'
please help me to solve this problem. thank you.
解决方案The line
VALUE method_test(VALUE y) {
Should be
VALUE method_test(VALUE self, VALUE y) {
The error message is thrown by
NUM2INT(y)
becausey
is the rootObject
of the script in your code as-is. The root object is what you got because you mixed in your module at the top level of the script. If you had mixed in to another class, you would have got an instance of that class instead.All native extension methods should take a
self
parameter (the first one if you have fixed number of params) which is the context that they are being called in (aModule
,Class
or instance of aClass
). It is how you getfoo
into the extension when you callfoo.test
. This might seem odd when both Ruby and C++ do this automatically (self
in Ruby, andthis
in C++): However it is necessary to haveself
appear as param because the Ruby internal API is written in C, which does not support OO directly - instead the Ruby API defined inruby.h
expects you to write and use C functions that take references to the current object as one of the params.In addition you are making a call to
Circle( int radius )
- which does not exist (although the compiler may be kind and coercex
for you automatically). You probably want to usedouble
variables throughout and useNUM2DBL(y)
andDBL2NUM( cir->getArea() )
这篇关于创建ruby C ++扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!