Wrap a C library with Ruby

This article explains how C functions can be used from within Ruby. There are two ways: the new way is to use a foreign function interface and the old way is to write a Ruby extension.

To make the example real, it will add Ruby spport for the AFsplitter library used by LUKS.

Prepare the shared library

Begin by downloading C library:

$ curl http://clemens.endorphin.org/AFsplitter-0.1.tar.bz2 | tar jxvf -

It's Makefile statically links a test program. I modified this to provide a shared library:

LIBOBJ=af.o sha1.o XORblock.o random.o

$(TEST): $(TEST).o $(LIB)
    $(CC) $^ -o $@ $(LIB)

    $(CC) $^ -o $@ -shared

    rm -f $(OBJ) $(LIBOBJ) $(LIB) $(TEST)

Then, I confirmed that I could built and run the test:

$ make
Data equal, should be equal
Data not equal, should be not equal

The following sections will make it possible to use the shared library, libafsplit.so, from Ruby.


Ruby-FFI, the Ruby foreign function interface lets us write Ruby code that uses functions in a C library.

Create a gem

$ bundle gem afsplitter

copy afsplitter.so to lib

add dependency for ffi into gemspec; complete documentation entries in gemspec.

write lib/afsplitter.rb

write test/test_afsplitter.rb

build with rake build

test with rake

commit to repo

set up remote (i.e github or gitolite) and push

release gem with rake release



This article explains a way to make Ruby bindings for an existing C library. In particular, using SWIG to make a wrapper for the AFsplitter library used by LUKS.

Install required packages:

$ sudo pacman -S swig

Create a gem

$ bundle gem afsplitter 
$ cd afsplitter

Download and build the C library sources:

$ curl http://clemens.endorphin.org/AFsplitter-0.1.tar.bz2 | tar jxvf -
$ cd AFsplitter-0.1

Write a SWIG input file, afsplitter.i:

%module afsplitter
    #include "af.h"

append the function prototypes

$ sed -n -r 's/^(int AF_.*;)/extern \1/p' af.h >> afsplitter.i

Generate wrapper:

$ swig -ruby -autorename afsplitter.i

Write extconf.rb that builds a Makefile:

$ echo -e "require 'mkmf'\ncreate_makefile('afsplitter')" > extconf.rb

Save existing Makefile and make new one

Create a gem

$ bundle gem afsplitter 

Create a SWIG interface file

More gem stuff

also hoe, jeweler, bundler and ore.