Ruby解释器嵌入在C代码中

我只是从一本书中尝试一个简单的例子:我有一个sum.rb文件:

class Summer def sum(max) raise "Invalid maximum #{max}" if max < 0 (max*max + max)/2 end end 

还有一个embed_sum.c文件:

 #include  #include  int main ( int argc, char ** argv) { VALUE result; ruby_sysinit(&argc, &argv); RUBY_INIT_STACK; ruby_init(); ruby_init_loadpath(); rb_require("sum"); rb_eval_string("$summer = Summer.new"); rb_eval_string("$result = $summer.sum(10)"); result = rb_gv_get("result"); printf("Result = %d\n", NUM2INT(result)); return ruby_cleanup(0); } 

我编译它:

 gcc -Wall -lruby -I/usr/include/ruby-1.9.1/ embed_sum.c -o embed_sum 

当我启动./embed_sum时,它会从第一个rb_eval_string中给出一个分段错误。 我的ruby版本是:Archlinux上的ruby 1.9.3p125(2012-02-16修订版34643)[x86_64-linux]。

这个例子有什么问题?

你的问题的简短答案是改变行rb_require("sum");rb_require("./sum"); 。 这是Ruby 1.9.2中引入的更改,其中当前目录不再位于加载路径上。

更普遍的问题是嵌入式Ruby处理exception的方式。 Pickaxe书(我认为是你正在使用的书,它使用了一个类似的例子)有这样的说法:

如果Ruby代码引发exception但未捕获,则C程序将终止。 要解决这个问题,您需要执行解释器所做的操作并保护可能引发exception的所有调用。 这可能会变得混乱。

您需要考虑使用rb_protect函数来包装可能导致exception的Ruby调用。 Pickaxe书就是一个例子。