Обмен данными между Ruby и Stack Overflow

Я просматривал учебники о том, как встраивать Ruby в программу на C ++. Я узнал, как определить класс через «rb_define_class» и «rb_define_class_under» и методы через «rb_define_method». Теперь мне нужен хороший пример, который объясняет, как обернуть существующий объект C ++ (указатель) классом ruby, написанным на C ++. Пример:

    class MyClass
{
public:
MyClass();
void MyMethod();
};

VALUE myclass_init(VALUE self)
{
// I'd like to create a new MyClass instance and store its pointer inside "self"}

VALUE myclass_meth(VALUE self)
{
// Now i need to retrieve the pointer to the object and call its method
}

int main(int argc, char* argv[])
{
ruby_init();
ruby_init_loadpath();

VALUE myclass = rb_define_class("MyWrapperClass", rb_cObject);
rb_define_method(myclass, "initialize", (VALUE(*)(...))myclass_init, 0);
rb_define_method(myclass, "myWrappedMethod", (VALUE(*)(...))myclass_meth, 0);

// Loading ruby script skipped..

ruby_finalize();

return 0;
}

Мне также нужен способ для сбора мусора, чтобы освободить мой обернутый объект (и делать другие вещи). Извините за плохой английский и спасибо всем, кто попытается ответить на этот вопрос!

2

Решение

Для интеграции с управлением памятью в Ruby вам необходимо реализовать две функции, которые выделяют и освобождают память для одного из ваших объектов — ни одна из них не может принимать параметры. Ruby будет хранить вашу структуру данных C ++, «привязанную» к Ruby self ЗНАЧЕНИЕ, и вам нужно использовать несколько методов для создания этого вложения и получить на C ++ от self,

Ваш код был настолько близок, что я только что заполнил для вас пробелы:

class MyClass
{
public:
MyClass();
void MyMethod();
};

//////////////////////////////////////////////////////////
// The next five are the functions that you were missing
// (although you could factor this differently if you chose)

MyClass *rb_create_myclass_obj() {
return new MyClass();
}

void rb_delete_myclass_obj( MyClass *p_myclass ) {
delete p_myclass;
return;
}

VALUE myclass_as_ruby_class( MyClass *p_myclass , VALUE klass ) {
return Data_Wrap_Struct( klass, 0, rb_delete_myclass_obj, p_myclass );
}

VALUE myclass_alloc(VALUE klass) {
return myclass_as_ruby_class( rb_create_myclass_obj(), klass );
}

MyClass *get_myclass_obj( VALUE obj ) {
MyClass *p_myclass;
Data_Get_Struct( obj, MyClass, p_myclass );
return p_myclass;
}

//////////////////////////////////////////////////////////

VALUE myclass_init(VALUE self)
{
// You need do nothing here, Ruby will call myclass_alloc for
// you.
return self;
}

VALUE myclass_meth(VALUE self)
{
MyClass *p_myclass = get_myclass_obj( self );
p_myclass->MyMethod();

// If MyMethod returns some C++ structure, you will need to convert it
// Here's how to return Ruby's nil

return Qnil;
}

int main(int argc, char* argv[])
{
ruby_init();
ruby_init_loadpath();

VALUE myclass = rb_define_class("MyWrapperClass", rb_cObject);

// The alloc function is how Ruby hooks up the memory management
rb_define_alloc_func(myclass, myclass_alloc);

rb_define_method(myclass, "initialize", (VALUE(*)(...))myclass_init, 0);
rb_define_method(myclass, "myWrappedMethod", (VALUE(*)(...))myclass_meth, 0);

// Loading ruby script skipped..

ruby_finalize();

return 0;
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector