2014-02-27 3 views
4

Ruby-C++ 확장을 개발 중입니다. CPP 클래스에 비 정적 메서드를 작성해야하고 클래스 인스턴스를 사용하여 루비 클라이언트에서 해당 클래스 메서드를 호출해야합니다.Ruby-C++ 확장의 C++ 클래스에서 비 정적 메서드를 작성하는 방법은 무엇입니까?

require 'Test' 
include Test 

a = Mclass.new 

내가 루비 클라이언트에서 "Mclass"의 인스턴스를 얻을 수 있어요 :

#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); 
} 

또한 다음 루비 클라이언트 코드는 다음과 같습니다

다음은 MAIN.CPP입니다. 그러나 루비 클라이언트에서 클래스 비 정적 메소드를 호출하고 싶습니다. 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 객체 (VALUE)에 도달 할 수 있는지 확인해야합니다. 그렇지 않으면 마크 및 스윕 수집기가 클래스를 제거합니다. 테스트하는 동안 수동으로 GC를 호출하여 수집되지 않아야하는 일부 객체가 수집되는지 확인할 수 있습니다.

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

reinterpret_cast!

+0

감사합니다. – BSalunke