Pregunta

Estoy escribiendo una aplicación que las llamadas rubí código de c. Estoy teniendo un poco de dificultad y se preguntó si alguien me podría apuntar en la dirección rito.

Actualmente tengo en mi C.

#include ruby.h

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

Mi archivo de rubí se encuentra en el mismo directorio que mi archivo c y se llama myRubyFile.rb y contiene una definición de la función RubyFunction ().

Este es un corte hacia abajo de lo que realmente quiero hacer, simplemente por lo que es más fácil de leer para los demás. Yo sólo requieren alguna información sobre si este es el método correcto de código de llamada rubí de mi archivo c.

Regards

¿Fue útil?

Solución

Respuesta corta:

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

Respuesta larga:

El primer argumento es el rb_funcall receptor de la llamada al método.

Suponiendo que defined fuera RubyFunction() de cualquier clase explícita o contexto módulo, a continuación, se añade a los eigenclass del, objeto principal implícita en el "nivel superior" de todos los rubíes vm .

En rubí, este objeto es accesible como el self de nivel superior:

$ 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

En C bajo 1,9 es accesible, como se indica anteriormente.

Otros consejos

Trato de utilizar el siguiente enfoque:

estructura básica para compartir datos

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

Crea una función de llamada de objetos de rubí en alguna parte de su código

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

En alguna parte de su código ...

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

Es siempre una buena idea para rb_funcall envoltura con rb_protect.

Otra cosa interesante es conocer los parámetros de la devolución de llamada, un enfoque es la siguiente

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

eso no me gusta a Ruby llamada desde el interior de C a menos que tenga proyecto complejo C, que no desea volver a la acumulación de rubí.

Hay dos formas de interactuar entre C y rubí. Se puede extender rubí con código escrito en C. Ver TRAGO .

O puede incrustar rubí, ver aquí , aquí y aquí .

Por cierto, ¿qué es lo que usted menciona es "incrustar" rubí, no "extender" rubíes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top