2012-03-08 100 views
1

我只是嘗試從一本書一個簡單的例子: 我有一個sum.rb文件:Ruby解釋器在C代碼嵌入

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]。

這個例子有什麼問題?

+2

喲dawg,我聽說你喜歡代碼,所以我們把一些代碼放在你的代碼中... – tbert 2012-03-08 14:36:08

+0

我得到'/usr/include/ruby-1.9.1/ruby/ruby.h:24:25:fatal錯誤:ruby/config.h:沒有這樣的文件或目錄 編譯已終止。「 – Reactormonk 2012-03-08 14:41:20

+0

@Tass我遲了一年,但對於遇到同樣問題的用戶,您需要添加'/ usr/include/ruby​​/'或類似於你的包含路徑以找到config.h。一個簡單的'find/usr/include -name config.h'會找到正確的路徑。 – Vortico 2013-06-18 00:31:08

回答

3

您的問題的簡短答案是將行rb_require("sum");更改爲rb_require("./sum");。這是Ruby 1.9.2中引入的更改,其中當前目錄不再位於加載路徑中。

更常見的問題是嵌入式Ruby處理異常的方式。鎬頭書(我認爲這是你使用這本書,它採用了類似的例子)有這樣一段話:

If the Ruby code raises an exception and it isn't caught, your C program will terminate. To overcome this, you need to do what the interpreter does and protect all calls that could raise an exception. This can get messy.

你需要考慮使用rb_protect功能包到Ruby調用,可能會導致異常。 Pickaxe書籍就是一個例子。

+0

Thx,我會測試一下 – cedlemo 2012-03-08 15:58:11