How to Embed Ruby in C++

Ruby interpreter embed in C code

The short answer to your problem is to change the line rb_require("sum"); to rb_require("./sum");. This is the change introduced in Ruby 1.9.2 where the current directory is no longer on the load path.

The more general problem is the way embedded Ruby deals with exceptions. The Pickaxe book (which I think is the book you're using, it uses a similar example) has this to say:

If the Ruby code raises an exception and it isn't caught, your C program will terminate. To overcome this, you need to do what the interpreter does and protect all calls that could raise an exception. This can get messy.

You'll need to look into using the rb_protect function to wrap calls to Ruby that might cause an exception. The Pickaxe book has an example of this.

How to embed Ruby in C++?

swig is probablly the way to go..... but ruby doesnt embed too well......

if you want a language that embeds nicely into C++, try lua

Embedding Ruby, calling a function from C

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:

The first argument to rb_funcall is the receiver of the method call.

Assuming you defined RubyFunction() outside of any explicit class or module context, then it is added to the eigenclass of the implicit, main object at the "top level" of every ruby vm.

In ruby, this object is accessible as the top-level 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

In C under 1.9 it is accessible as indicated above.

embed ruby code in C

You should not hard-code the full path of a header file like

#include </usr/include/ruby-1.9.1/ruby/ruby.h>

proper is

#include <ruby.h>

and told your gcc to search the header file via CFLAGS and libariy via LD_FLAGS, simply command without makefile could be:

gcc -o demo.exe -I/path/to/ruby/headers rubydemo.c -L/path/to/ruby/lib -lruby-libary-name

Using rb_require with rb_protect to embed Ruby in C

Solutions that works well:

int error;
rb_protect( (VALUE (*)(VALUE))rb_require, (VALUE) "./test", &error);

or

int error;
rb_protect( RUBY_METHOD_FUNC(rb_require), (VALUE) "./test", &error);

or

VALUE require_wrap(VALUE arg)
{
return rb_require("./test");
}
/*in main:*/
rb_protect( require_wrap, 0, & error);


Related Topics



Leave a reply



Submit