Embedding Ruby as plugin

Discussion in 'Ruby' started by Tobias Grimm, Aug 16, 2004.

  1. Tobias Grimm

    Tobias Grimm Guest

    Hi!

    I have an application written in C++, that provides a plugin interface. What I
    would like to do now, is to implement a plugin, that allows to execute a ruby
    script, like this:

    1) Application loads plugin.so
    2) Application invokes plugin
    3) Plugin creates object "interface" of class Interface
    4) Plugin loads rubyscript.rb
    5) rubyscript.rb uses interface object created in 3) to send messages to the plugin

    I used SWIG to create a wrapper for the Interface class that the ruby script
    should use. If I simply wanted to create an ruby extension, the wrapper should
    just be compiled to a lib, that ruby can load with a require statement. But now
    the wrapper is part of the plugin, which itself is loaded by the application.
    How do I get the ruby script know about the Interface class and the interface
    object to use?

    Tobias
     
    Tobias Grimm, Aug 16, 2004
    #1
    1. Advertising

  2. Tobias Grimm wrote:
    > Hi!
    >
    > I have an application written in C++, that provides a plugin interface.
    > What I would like to do now, is to implement a plugin, that allows to
    > execute a ruby script, like this:
    >
    > 1) Application loads plugin.so
    > 2) Application invokes plugin
    > 3) Plugin creates object "interface" of class Interface
    > 4) Plugin loads rubyscript.rb
    > 5) rubyscript.rb uses interface object created in 3) to send messages to
    > the plugin
    >
    > I used SWIG to create a wrapper for the Interface class that the ruby
    > script should use. If I simply wanted to create an ruby extension, the
    > wrapper should just be compiled to a lib, that ruby can load with a
    > require statement. But now the wrapper is part of the plugin, which
    > itself is loaded by the application. How do I get the ruby script know
    > about the Interface class and the interface object to use?


    Not sure I understand. Where is the ruby interpreter in this picture?
    Your C++ app embeds it? Or plugin.so embeds it?

    What if you just set a global variable, $interface, before loading
    rubyscript.rb, which references this global?

    Is the problem then that you don't want to use a global, for the usual
    good reasons?
     
    Joel VanderWerf, Aug 17, 2004
    #2
    1. Advertising

  3. Tobias Grimm

    Tobias Grimm Guest

    Joel VanderWerf wrote:

    > Not sure I understand. Where is the ruby interpreter in this picture?
    > Your C++ app embeds it? Or plugin.so embeds it?


    plugin.so embeds it. I can't change the C++ app, it will never know, that one of
    it's plugins uses ruby.

    > What if you just set a global variable, $interface, before loading
    > rubyscript.rb, which references this global?
    >
    > Is the problem then that you don't want to use a global, for the usual
    > good reasons?


    No... I could live with some globals. Althought I would probably use a static
    factory method to return an Interface instance.

    My problem is, that I don't know how to make my C++ classes, which are linked to
    plugin.so, available to ruby which is embedded by plugin.so.

    A usal ruby extension would just load the extension from a lib. But in my case
    the lib containing the extension itself is running the ruby script

    Lets say, I have interface.h which defines a C++ class "Interface" with a static
    methode that returns a singleton instance of this class. It may get the instance
    from a global variable.
    SWIG now creates an interface_wrap.c, which I compile and link to my plugin.so.
    Within the plugin.so some methode should now run the ruby script, calling
    ruby_init and all the stuff to handle exceptions and so on.
    But how do I let the ruby script know, that there is a class "Interface"? A
    simple 'require "interface"' doesn't work.

    Tobias
     
    Tobias Grimm, Aug 17, 2004
    #3
  4. Tobias Grimm

    Richard Dale Guest

    Tobias Grimm wrote:

    > Hi!
    >
    > I have an application written in C++, that provides a plugin interface.
    > What I would like to do now, is to implement a plugin, that allows to
    > execute a ruby script, like this:
    >
    > 1) Application loads plugin.so
    > 2) Application invokes plugin
    > 3) Plugin creates object "interface" of class Interface
    > 4) Plugin loads rubyscript.rb
    > 5) rubyscript.rb uses interface object created in 3) to send messages to
    > the plugin
    >
    > I used SWIG to create a wrapper for the Interface class that the ruby
    > script should use. If I simply wanted to create an ruby extension, the
    > wrapper should just be compiled to a lib, that ruby can load with a
    > require statement. But now the wrapper is part of the plugin, which itself
    > is loaded by the application. How do I get the ruby script know about the
    > Interface class and the interface object to use?

    I'm not familiar with the code generated by SWIG, but you can start ruby and
    define a class from C like this:

    ruby_init();
    ruby_run();

    interface_module = rb_define_module("Interface");
    interface_class = rb_define_class_under(interface_module, "Interface",
    rb_cObject);

    # I assume Swig generates various wrapper methods like this:
    rb_define_method(interface_class, "foobar", foo_bar, 1);
    ...


    rb_require("rubyscript.rb");

    # Call an initialization method to create the "interface" instance
    rb_funcall(interface_class, rb_intern("init_rubyscript"), 0);

    -- Richard
     
    Richard Dale, Aug 17, 2004
    #4
  5. Tobias Grimm

    Tobias Grimm Guest

    Richard Dale wrote:

    > # Call an initialization method to create the "interface" instance
    > rb_funcall(interface_class, rb_intern("init_rubyscript"), 0);


    You're totally right. I missed calling the init function generated by SWIG. It's
    called Init_modulename(void). Normally ruby invokes this init function
    automatically, when loading an extension. But in my case, I've to do it myself.

    Thanks a lot!

    Tobias
     
    Tobias Grimm, Aug 17, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. PilotYid
    Replies:
    1
    Views:
    630
    Andrew Thompson
    Oct 31, 2005
  2. Marcin Cenkier
    Replies:
    1
    Views:
    5,428
    Marcin Cenkier
    Apr 12, 2006
  3. Jimmy
    Replies:
    0
    Views:
    513
    Jimmy
    Mar 15, 2007
  4. Replies:
    1
    Views:
    731
  5. Glenn Lewis
    Replies:
    3
    Views:
    134
    Phil Tomson
    Jan 6, 2004
Loading...

Share This Page