CSC/ECE 517 Spring 2014/ch1 1w1h jg
Ruby libraries to load objects of other languages at run time
Ruby is a dynamic, reflective, object-oriented, general-purpose programming language. It is easy to extend Ruby with new features by writing code in Ruby. But every now and then extending ruby with low-level languages, such asC/C++/Java is also necessary.
Currently, various kinds of languages codes could be invoked from within ruby. The extension for C/C++ and Java are focused here.
Ruby C/C++ extensions<ref>http://java.ociweb.com/mark/NFJS/RubyCExtensions.pdf</ref>
By extending Ruby with C. The C libraries could be used directly in Ruby applications. Ruby could call C codes in three ways: interpreter API, RubyInline, SWIG.
interpreter API
Ruby interpreter is implemented in C, its API can be used and no special API added for interacting with C like Java’s JNI is needed.
The files needed include:
- extconf.rb
Used to generate Makefile
Platform-specific Makefiles for compiling C extensions to Ruby is needed to be generated firstly.
A simple sample is like below:
create a file containing the following, named extconf.rb by convention
require 'mkmf' extension_name = 'name' dir_config(extension_name) create_makefile(extension_name)
And use by running
ruby extconf.rb make
Then generates
.so under UNIX/Linux .so under Windows when building with Cygwin .bundle under Mac OS X
- C File
C codes to be invoked from Ruby
An example Hello.c is shown below
#include <ruby.h> #include <stdio.h> // These C functions will be associated with // methods of a Ruby class on the next page. static VALUE hello(VALUE self, VALUE arg) { char* name = RSTRING(arg)->ptr; printf("Hello %s!\n", name); return Qnil; } static VALUE goodbye(VALUE class) { printf("Later dude!\n"); return Qnil; } // This is called when the Ruby interpreter loads this C extension. // The part after "Init_" is the name of the C extension specified // in extconf.rb, not the name of the C source file. void Init_hello() { // Create a Ruby module. VALUE myModule = rb_define_module("MyModule"); // Create a Ruby class in this module. // rb_cObject is defined in ruby.h VALUE myClass = rb_define_class_under(myModule, "MyClass", rb_cObject); // Add an instance method to the Ruby class. int arg_count = 1; rb_define_method(myClass, "hello", hello, arg_count); // Add a class method to the Ruby class. arg_count = 0; rb_define_module_function(myClass, "goodbye", goodbye, arg_count); }
- Ruby File
Ruby code that invokes C code
An example client.rb is shown as below
require 'hello' include MyModule # so MyClass doesn't need MyModule:: prefix obj = MyClass.new # MyClass is defined in C obj.hello('Mark') # calling an object method MyClass.goodbye # calling a class method
Finally we could build and run
ruby extconf.rb make ruby client.rb
Then the output will display as
Hello Mark! Later dude!
RubyInline
RubyInline allows C code to be imbedded in Ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it.
To setup RubyInline, just use
gem install rubyinline
SWIG
SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of target languages including common scripting languages such as Perl, PHP, Python, Tcl and Ruby.
As an example, building Ruby Extensions under Windows 95/NT is shown as below Building a SWIG extension to Ruby under Windows 95/NT is roughly similar to the process used with Unix.
C:\swigtest> ruby extconf.rb C:\swigtest> nmake C:\swigtest> nmake install
Ruby JAVA extensions
To extend Ruby with JAVA, the JRuby is a good tool to use. JRuby is a high performance, stable, fully threaded Java implementation of the Ruby programming language. It is a Ruby interpreter written entirely in Java and can use Java capabilities from Ruby as well as can use Ruby capabilities from Java.
Using JRuby From Command-Line
- Steps to install
– download a binary release here
– unzip/untar the downloaded archive
– set JRUBY_HOME environment variable to point to resulting directory
– add $JRUBY_HOME/bin to PATH
- Steps to use
– jruby {script-name}
- Example
– hello.rb
name = ARGV[0] || "you" puts "Hello #{name}!"
– run with
jruby hello.rb
outputs
Hello you!
– run with
jruby hello.rb Mark
outputs
Hello Mark