Ruby解释器嵌入在C代码中

时间:2012-03-08 14:13:03

标签: c ruby embed

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

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

和embed_sum.c文件:

#include <stdio.h>
#include <ruby/ruby.h>
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]。

这个例子有什么问题?

1 个答案:

答案 0 :(得分:3)

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

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

  

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

您需要考虑使用rb_protect函数来包装可能导致异常的Ruby调用。 Pickaxe书中有一个例子。