Ruby Programming/C Extensions

= C Extensions =

Extending ruby with C extensions is relatively easy. The README.EXT file included with the source code for ruby is very useful and talks about creating extensions to ruby, converting ruby to c types and vice-versa.

Typically a C extension looks like

file go.c
 * 1) include "ruby.h"

void Init_go {

}

Then you create a makefile for it by using the mkmf library.

Extension Config File
This file makes the makefile with the mkmf library. The makefile is then used with the make program to make the extension.

A simple config file looks like

file config.rb require "mkmf"

create_makefile("go")
 * 1) the string is the init function's suffix in the .c source file. e.g, void Init_go
 * 2) it's also the name of the extension. e.g, go.so

Process to Make an Extension
This is a short overview of a simple extension that prints the classic phrase "Hello!" You need to know C and read the README.EXT file if you want to create something more useful.

Create a new folder and add the two files below into it.

file hello.c VALUE hello(VALUE self);
 * 1) include 

void Init_hello { rb_define_global_function("hello", hello, 0); }

VALUE hello(VALUE self) { printf("Hello!\n");

return Qnil; }

file config.rb require 'mkmf';

extname = 'hello';
 * 1) extension name

create_makefile(extname);

Now from the command prompt run the commands: ruby config.rb make (replace with "nmake" for Windows SDK)

Now to test it. Type this to load the extension. irb -r .\hello.so

Type in "hello" and IRB will echo back.

irb(main):002:0>hello Hello! => nil

Differences between 1.9 and 1.8
1.9 has at least the difference of having more macros defined. Here's how to get them in 1.8 (some of this from Phusion passenger's code).

#define RARRAY_LEN(ary) RARRAY(ary)->len #define RSTRING_PTR(str) RSTRING(str)->ptr #define RSTRING_LEN(str) RSTRING(str)->len
 * 1) ifndef RARRAY_LEN
 * 1) endif
 * 2) ifndef RSTRING_PTR
 * 1) endif
 * 2) ifndef RSTRING_LEN
 * 1) endif

#define RBIGNUM_DIGITS(obj) RBIGNUM(obj)->digits
 * 1) ifndef RBIGNUM_DIGITS
 * 1) endif

C extensions in Jruby
You can use java extensions in jruby (obviously). You can also use ffi and/or ffi-inliner gem to use native C extensions.