Last modified on 14 March 2014, at 21:20

Ruby Programming/C Extensions

C ExtensionsEdit

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 FileEdit

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 ExtensionEdit

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.8Edit

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 JrubyEdit

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

External LinksEdit

A tutorial. A rundown.