Ruby Programming/C Extensions

C Extensions

edit

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

#include "ruby.h"

void Init_go() {

}

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


Extension Config File

edit

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"

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

Process to Make an Extension

edit

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

#include <ruby.h>
VALUE hello(VALUE self);

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

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

  return Qnil;
}

file config.rb

require 'mkmf';

# extension name
extname = 'hello';

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

edit

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).


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

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

C extensions in Jruby

edit

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

edit

A tutorial.