在C和exntend中嵌入Ruby

Embed Ruby in C and exntend

本文关键字:Ruby exntend      更新时间:2023-10-16

我有一个需求,需要在C++中嵌入Ruby代码(我可以实现这一点)并扩展一些功能。当我试图调用(需要)我的扩展模块时,程序会失败。

我粘贴了下面的代码:

main.cpp

#include <ruby.h>
static VALUE Sum(VALUE rb_self, VALUE rb_param1, VALUE rb_param2)
{
    double val1 = NUM2DBL(rb_param1);
    double val2 = NUM2DBL(rb_param2);
    return rb_float_new(val1+val2);
}
void Init_myMod()
{
    myMod = rb_define_module("myMod");
    rb_define_module_function(myMod, "Sum", Sum, 2);
}
int main()
{
 ... Init ruby method...
    rb_require("myRubyfile");
    Init_myMod(); // This is where I need to push my ruby extension.
    rb_funcall(rb_mKernel, rb_intern("helloworld"), 0 , NULL);
.... 
}

myRubyfile.rb

require "myMod"
def helloworld()
    puts "Hello world"
    #puts "Sum of.. " + myMod.sum(4, 5)
end

问题是,如果我不使用require"myMod",代码就会工作并打印"Hello World",但如果我使用require。。,代码转储。

这是我的需求,我需要将ruby脚本嵌入到C中,并在ruby(扩展)中重用一些C方法。

有人能帮我吗?

您得到的是segfault,因为Ruby VM在出现未捕获的异常时会出现segfault。您需要使用类似rb_rescuerb_protect的东西来包装可能引发异常的代码。

require "myMod"正在引发异常,因为require仅用于加载文件。您不需要任何东西,因为您直接在VM的内存中创建模块。那么…为什么会出错?好吧,如果你用Ruby编写你的模块,你会得到一个语法错误:

module myMod
  ...
end
# SyntaxError: class/module name must be CONSTANT

但是,当您使用rb_define_module而不是引发异常时,Ruby会做一件棘手的事情:它创建模块,但不将其暴露给Ruby代码。为了向Ruby公开模块,只需使名称有效即可:

// .cpp
rb_define_module("MyMod");

# .rb
puts "Sum of.. " + MyMod.Sum(4, 5).to_s

这样的东西应该可以工作。为您的ruby脚本文件制作一个bat脚本,并将系统更改为适当的系统调用。不确定system()是否在Windows中工作。我已经用这种方式运行了许多bash脚本,所以我认为你可以在Windows中做同样的事情。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    puts("Starting now:");
    system("/path_to_script/script_name");
    return 0;
}