2014-02-27 50 views
4

我正在開發一個Ruby-C++擴展。 我必須在CPP類中編寫非靜態方法,並且我必須使用類實例在Ruby客戶端中調用該類方法。如何在C++類的Ruby-C++擴展中編寫非靜態方法?

以下是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); 
} 

而且下面是紅寶石客戶端代碼:

require 'Test' 
include Test 

a = Mclass.new 

我能夠在Ruby客戶端獲得 「Mclass」 的實例。但是希望在ruby客戶端中調用類非靜態方法。 如何在CPP類中添加非靜態方法?

回答

2

你必須用C綁定將你的函數封裝在C函數中。將對象(又名this)和所有參數傳遞給該C函數並調用none靜態函數。你可以看看https://github.com/TorstenRobitzki/Sioux/blob/master/source/rack/bayeux.cpp,其中bayeux_server是一個帶有可以從ruby調用的函數update_node()的類。

另一個好的起點是http://ruby-doc.com/docs/ProgrammingRuby/一章「擴展Ruby」。 Basicaly,你必須確定,垃圾收集器可以訪問存儲在你自己的類中的所有Ruby對象(VALUE),否則,標記和清除收集器將刪除它們。在測試過程中,您可以手動調用GC以查看是否收集了某些不應收集的對象。

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

請勿使用reinterpret_cast

+0

謝謝,它的工作 – BSalunke

相關問題