CSC/ECE 517 Spring 2014/ch1 1w1h jg

From Expertiza_Wiki
Revision as of 22:40, 4 February 2014 by Qjia2 (talk | contribs)
Jump to navigation Jump to search

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 [www.jruby.org 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