Ruby Programming/C Extensions

From Wikibooks, open books for an open world
< Ruby Programming
Jump to: navigation, search

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.

External Links[edit]

A tutorial. A rundown.