如何在Ruby-C ++扩展中编写C ++类中的非静态方法?

时间:2014-02-27 15:25:03

标签: c++ ruby ruby-c-extension

我正在开发Ruby-C ++扩展。 我必须在CPP类和I中编写非静态方法 必须使用类实例在ruby客户端中调用该类方法。

以下是main.cpp:

#include "ruby.h"
#include <iostream>
using namespace std;

class Mclass
{
        public:
        int i;
        static VALUE newMethod(VALUE self);
        static VALUE newInitialize(VALUE self);
};

VALUE Mclass::newMethod(VALUE self)
{
        cout<<"It is newMethod() method of class Mclass"<< endl;
        return Qnil;

}
VALUE Mclass::newInitialize(VALUE self)
{
        cout<<"It is newInitialize() method of class Mclass"<< endl;
        return Qnil;
}

extern "C" void Init_Test(){
   VALUE lemon = rb_define_module("Test");
   VALUE mc = rb_define_class_under(lemon, "Mclass", rb_cObject);
   rb_define_method(mc, "new",
      reinterpret_cast< VALUE(*)(...) >(Mclass::newMethod), 0);
   rb_define_method(mc, "initialize",
      reinterpret_cast< VALUE(*)(...) >(Mclass::newInitialize), 0);
}

以下是ruby客户端代码:

require 'Test'
include Test

a = Mclass.new

我能够在ruby客户端获得“Mclass”的实例。但是想在ruby客户端中调用类非静态方法。 如何在CPP类中添加非静态方法?

1 个答案:

答案 0 :(得分:2)

您必须使用C绑定将函数包装在C函数中。将对象(也称为this)和所有参数传递给该C函数并调用none静态函数。你可以查看https://github.com/TorstenRobitzki/Sioux/blob/master/source/rack/bayeux.cpp,其中bayeux_server是一个带有函数update_node()的类,可以从ruby调用。

另一个好的起点是http://ruby-doc.com/docs/ProgrammingRuby/章“扩展Ruby”。基本上,您必须确保垃圾收集器可以访问存储在您自己的类中的所有Ruby对象(VALUE),否则,标记和扫描收集器将删除它们。在测试期间,您可以手动调用GC以查看是否收集了一些不应收集的对象。

extern "C" VALUE newInitialize(VALUE self)
{
    MyClass* s = 0;
    Data_Get_Struct( self, MyClass, s );
    s->newInitialize();
}

请勿使用reinterpret_cast