Ruby attachment, function call from C

I am writing an application that calls ruby ​​code with c. I find it a bit difficult and wonder if anyone can point me in the direction of the rite.

I currently have C.

#include ruby.h

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

My ruby ​​file is in the same directory as my c file and is called myRubyFile.rb and contains the definition of the RubyFunction () function.

This is an abbreviation of what I really want to do, just making it more readable to others. I just need some feedback as to whether this is the correct method to call the ruby ​​code from my c file.

Hi

+3
source share
3 answers

Short answer:

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);

Longer answer:

rb_funcall - .

, def ined RubyFunction() - , eigenclass " " ruby ​​vm.

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 , .

+5

:

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_funcall rb_protect.

- , -

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);
0

ruby ​​ C, C, ruby.

C ruby. ruby ​​, C. . SWIG.

Or you can insert ruby, see here , here and here .

By the way, what you mentioned is “embed” a ruby, not “expand” a ruby.

-1
source

Source: https://habr.com/ru/post/1744747/


All Articles