Я разрабатываю расширение Ruby-C ++.
Я должен написать нестатический метод в классе CPP, и я
должен вызвать этот метод класса в клиенте 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
Я могу получить экземпляр «Mclass» в клиенте ruby. Но хочу вызвать нестатический метод класса в клиенте ruby.
Как я могу добавить нестатический метод в классе CPP?
Вы должны обернуть свою функцию в C-функцию с помощью C-привязки. Передайте объект (он же) и все аргументы этой функции C и вызовите статическую функцию. Вы можете взглянуть на https://github.com/TorstenRobitzki/Sioux/blob/master/source/rack/bayeux.cpp, где bayeux_server — это класс с функцией update_node (), которая может быть вызвана из ruby.
Другая хорошая отправная точка http://ruby-doc.com/docs/ProgrammingRuby/ глава «Расширение Ruby». По сути, вы должны убедиться, что сборщик мусора может достичь всех объектов Ruby (ЗНАЧЕНИЙ), которые хранятся в вашем собственном классе, или иначе сборщик меток и свипов удалит их. Во время ваших тестов вы можете вручную вызвать GC, чтобы увидеть, собираются ли некоторые объекты, которые не должны собираться.
extern "C" VALUE newInitialize(VALUE self)
{
MyClass* s = 0;
Data_Get_Struct( self, MyClass, s );
s->newInitialize();
}
Не использовать reinterpret_cast
!
Других решений пока нет …