CSC/ECE 517 Spring 2014/ch1 1w1h jg: Difference between revisions
No edit summary |
No edit summary |
||
Line 154: | Line 154: | ||
<pre> | <pre> | ||
Hello Mark | Hello Mark | ||
</pre> | |||
=== Using JAVA Classes in JRuby === | |||
To use java classes in JRuby, the program must require 'java' | |||
There several options to provide full names of Java classes to be used in JRuby | |||
*'''option #1''' | |||
provide full name when using | |||
<pre> | |||
frame = javax.swing.JFrame.new('My Title') | |||
</pre> | |||
*'''option #2''' | |||
assign full class name to a constant | |||
<pre> | |||
JFrame = javax.swing.JFrame | |||
frame = JFrame.new('My Title') | |||
</pre> | |||
*'''option #3''' | |||
use include_class | |||
<pre> | |||
include_class 'javax.swing.JFrame' | |||
frame = JFrame.new('My Title') | |||
</pre> | |||
*'''option #4''' | |||
use include_class with an alias | |||
<pre> | |||
include_class('java.lang.String') do |pkg_name, class_name| | |||
"J#{class_name}" | |||
end | |||
msg = JString.new('My Message') | |||
</pre> | |||
*'''option #5''' | |||
use include_package | |||
<pre> | |||
module Swing | |||
include_package 'javax.swing' | |||
end | |||
frame = Swing::JFrame.new('My Title') | |||
</pre> | </pre> |
Revision as of 22:48, 4 February 2014
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
Using JAVA Classes in JRuby
To use java classes in JRuby, the program must require 'java'
There several options to provide full names of Java classes to be used in JRuby
- option #1
provide full name when using
frame = javax.swing.JFrame.new('My Title')
- option #2
assign full class name to a constant
JFrame = javax.swing.JFrame frame = JFrame.new('My Title')
- option #3
use include_class
include_class 'javax.swing.JFrame' frame = JFrame.new('My Title')
- option #4
use include_class with an alias
include_class('java.lang.String') do |pkg_name, class_name| "J#{class_name}" end msg = JString.new('My Message')
- option #5
use include_package
module Swing include_package 'javax.swing' end frame = Swing::JFrame.new('My Title')