簡體   English   中英

嵌入Ruby,從C調用函數

[英]Embedding Ruby, calling a function from C

我正在編寫一個從c調用ruby代碼的應用程序。 我有點困難,想知道是否有人能指出我的儀式方向。

我目前在我的C.

#include ruby.h

main()
{
  ruby_init();
  rb_require("myRubyFile");
  rb_funcall(rb_module_new(), rb_intern("RubyFunction"), 0, NULL);
}

我的ruby文件與我的c文件位於同一目錄中,名為myRubyFile.rb,包含函數RubyFunction()的定義。

這是我實際想要做的事情的減少,只是讓其他人更具可讀性。 我只是需要一些反饋來判斷這是否是從我的c文件中調用ruby代碼的正確方法。

問候

簡短回答:

extern VALUE rb_vm_top_self(void); /* Assumes 1.9.  Under 1.8, use the global
                                    * VALUE ruby_top_self
                                    */
...
rb_funcall(rb_vm_top_self(),           /* irb> RubyFunction()                   */
           rb_intern("RubyFunction"),  /* irb> self.RubyFunction() # same thing */
           0,
           NULL);

更長的回答:

rb_funcall的第一個參數是方法調用的接收者

假設你def INED RubyFunction()的任何顯式類或模塊上下文之外,則在每一個紅寶石VM的“頂級”加入到隱式的, 主被攝體的eigenclass。

在ruby中,此對象可作為頂級self

$ cat myRubyFile.rb
# file: myRubyFile.rb
def foo
  puts "foo"
end

$ irb
irb> require "myRubyFile"
=> true
irb> foo
foo
=> nil
irb> self.foo()    # same thing, more explicit
foo
=> nil
irb> self
=> main

在C 1.9以下,如上所述可以訪問。

我嘗試使用以下方法:

共享數據的基本結構

typedef struct ruby_shared_data {
    VALUE obj;
    ID method_id;
    int nargs;
    VALUE args[4];
} ruby_shared_data;

在代碼的某些部分為調用ruby對象創建一個函數

static VALUE ruby_callback(VALUE ptr) {

    ruby_shared_data *data = (ruby_shared_data*)ptr;

    return rb_funcall2(data->obj,data->method_id,data->nargs,data->args);
}

在你的代碼的某些部分......

    ruby_shared_data rbdata;

    rbdata.obj = obj;
    rbdata.method_id = rb_intern("mycallback");
    rbdata.nargs = 1;
    rbdata.args[0] = rb_str_new2("im a parameter");

    int error = 0;
    VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);

    if (error)
            throw "Ruby exception on callback";

使用rb_protect包裝rb_funcall總是一個好主意。

另一個有趣的事情是知道回調的參數,一種方法如下

ruby_shared_data rbdata;

rbdata.obj = callback;
rbdata.method_id = rb_intern("arity"); 
rbdata.nargs = 0;

int error = 0;
VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);

if (error)
        throw "Ruby exception on callback";

narguments = NUM2INT(result);

我不喜歡從C里面調用ruby,除非你有一個復雜的C項目,你不想在ruby中重新構建。

C和ruby之間有兩種交互方式。 您可以使用C編寫的代碼擴展ruby。請參閱SWIG

或者你可以嵌入紅寶石,看到這里這里這里

順便說一句,你提到的是“嵌入”紅寶石,而不是“延伸”紅寶石。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM