c++ - 在 Ruby 和 C++ 之间交换数据

标签 c++ ruby embedded-ruby

我一直在浏览有关如何将 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;
    }

我还需要一种方法来处理垃圾收集,以便释放我的包装对象(并执行其他操作)。抱歉我的英语不好,感谢所有尝试回答这个问题的人!

最佳答案

要与 Ruby 的内存管理集成,您需要实现两个函数来为您的对象之一分配和释放内存 - 两者都不能带参数。 Ruby 将存储“附加”到 Ruby 的 C++ 数据结构 self VALUE,您需要使用几种方法来创建该附件,并从 self 获取您的 C++ .

到目前为止,您的代码足够接近,我刚刚在这里为您填补了空白:

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

关于c++ - 在 Ruby 和 C++ 之间交换数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20702109/

相关文章:

c++ - 文件不存在 - 相关错误。构建开源应用程序 QCAD 的问题

c++ - 全局鼠标 Hook 导致应用程序崩溃(c++/windows 7)

c++ - 我如何在 std::vector 中存储没有复制构造函数的类?

Ruby Net::HTTP 超时

ruby - 如何在 C(实际上是 swift)应用程序中完全重新初始化嵌入式 ruby​​ VM?

c++ - 在 C++ 程序中嵌入 ruby​​ 源时出错

css - 如何在样式标签中添加嵌入式 ruby

c++ - 如何在使用派生实例调用模板基类的好友函数时避免使用 “std::static_pointer_cast”

ruby - 安装 gem 时添加文件

ruby-on-rails - Ruby on Rails - 使用 logger.info "hi"给出 undefined variable 或方法错误,要更改/设置什么?