Question

Je suis en train d'écrire une application qui appelle ruby de code c.Je vais avoir un peu de difficulté et je me demandais si quelqu'un pouvait m'indiquer le rite de la direction.

J'ai actuellement dans mon C.

#include ruby.h

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

Mon fichier ruby est dans le même dossier que mon fichier c et est appelé myRubyFile.rb et contient une définition de la fonction RubyFunction().

C'est un coupé de ce que je veux faire, il suffit de le rendre plus lisible pour les autres.J'ai juste besoin de quelques commentaires quant à savoir si c'est la bonne méthode pour appeler du code ruby de mon c fichier.

Ce qui concerne

Était-ce utile?

La solution

Réponse courte:

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

Plus de réponse:

Le premier argument de rb_funcall est le récepteur de l'appel de méthode.

En supposant que vous defl'ined RubyFunction() en dehors de toute explicite de la classe ou du module contexte, il est alors ajouté à la eigenclass de l'implicite, l'objet principal "haut niveau" de chaque ruby vm.

En ruby, cet objet est accessible comme le haut-niveau 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

En C sous 1.9 il est accessible comme indiqué ci-dessus.

Autres conseils

J'essaie d'utiliser l'approche suivante:

De base de la structure de partager des données

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

Créer une fonction pour appeler les objets ruby sur une partie de votre code

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

Sur une partie de votre code...

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

Est toujours une bonne idée d'envelopper rb_funcall avec rb_protect.

Une autre chose intéressante est de savoir les paramètres de la fonction de rappel, une démarche est la suivante

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

Je n'aime pas à appeler ruby à partir de l'intérieur de C, sauf si vous avez des complexes C projet qui vous ne voulez pas à re-construire, en ruby.

Il y a deux façons d'interagir entre C et ruby.Vous pouvez étendre ruby avec le code écrit en C.Voir SWIG.

Ou vous pouvez incorporer des rubis, voir ici, ici et ici.

BTW, ce que vous dites est "embed" ruby, pas "d'extension" de ruby.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top