首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建ruby C++扩展

创建ruby C++扩展
EN

Stack Overflow用户
提问于 2013-12-04 06:37:44
回答 1查看 2.8K关注 0票数 5

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

C++头文件

代码语言:javascript
复制
  #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文件

代码语言:javascript
复制
  #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

代码语言:javascript
复制
    require 'mkmf'
    have_library( 'stdc++' );
    $CFLAGS << " -Wall"
    create_makefile( 'Test' );

run.rb

代码语言:javascript
复制
    require 'rubygems'

    require 'Test'

    include Test

    puts test(7)

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

代码语言:javascript
复制
          run.rb:7:in `test': can't convert Object into Integer (TypeError)
          from run.rb:7:in `<main>'

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-04 08:26:48

线

代码语言:javascript
复制
VALUE method_test(VALUE y) {

应该是

代码语言:javascript
复制
VALUE method_test(VALUE self, VALUE y) {

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

所有本机扩展方法都应该使用一个self参数(如果有固定数量的params,则为第一个参数),这是在其中调用它们的上下文( ModuleClassClass实例)。这就是当您调用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() )

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20368685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档