Running Ruby in C
Embedding Ruby requires one header
ruby.h, which includes a platform-specific
ruby/config.h. You will probably need to tell your compiler about the
include paths for these headers. You will also need to link with the Ruby lib.
On my machine, my minimal compiler options are
Though, if available, you should really use
pkg-config to get the appropriate
options for your distribution:
Including the Ruby interpreter in your C/C++ program is pretty simple. Just include the header and bookend your API calls with a couple function calls.
If the VM fails to start during
ruby_init() it will print an error and exit
your program! If you would rather have a softer error, you can instead call
ruby_setup() which returns a nonzero value if a failure occurred
(unfortunately it is not clear how to get a message for the error1).
If an error occurs during
rb_cleanup(), it returns a nonzero
value—otherwise it returns the argument you passed it. This allows a
little shortcut for returning an error status if the cleanup fails (as
demonstrated in the previous example).
During cleanup, the VM might evaluate more Ruby code (if you passed a block to
at_exit, for example) which could raise an exception.
these by returning a nonzero value and printing an error message. If you instead
ruby_finalize() they will be raised normally (see the section on
Exceptions for how to handle them).
Here’s an alternative example:
Tweaking the VM
You now have a bare-bones Ruby VM running, but you may want to set up a little
more stuff before you start running Ruby code. To set the name of the Ruby
$0) for error messages and such, use
To set up the load path so that gems can be loaded with
You can also pass options to the VM just like you would to
ruby on the command
line. This is handy for stuff like setting the warning level or verbose
The arguments to
argv just like a main function.
And just like the main of the
ruby program, the VM expects to get some Ruby
code when you call it. If you don’t give it the filename of a script to load or
code to run with
-e, it will try to read from
stdin. If you want to set
options but not run any Ruby code, you can pass it an empty line:
ruby_options() returns a “node” that represents the compiled Ruby code. In some
cases (such as a syntax error) the node will be invalid and you shouldn’t run
ruby_executable_node() checks for this. If the node is valid, you can run it
ruby_exec_node(). The state returned by
the pointer) and by
ruby_exec_node() will be nonzero if an exception was
raised while compiling or running the code. You can read the exception
yourself, or just pass
ruby_cleanup() and it will
print an appropriate error message.
Ruby currently doesn’t support any other way of compiling and running code separately3.
Now you’re ready to interact with Ruby! Go back to the C API.
error_print()to get an error message, but this function isn’t exposed to the API. Is this a normal exception? ↩
In my tests I couldn’t get flags like
-vto do anything. This could be related to
ruby_prog_init(). And really it should be possible to do this without parsing command line options. ↩
It looks like the function
rb_load_file()should do this, but I haven’t had any luck getting it to work. ↩