Skip to content


rdp edited this page · 29 revisions
Clone this wiki locally

How it works

With ffi-inliner you can inline snippets of C into your ruby script. The library takes care of compiling on the fly the C code interfacing to it through a generated FFI glue code. Using FFI you get interoperability among all ruby implementations that support FFI (e.g. JRuby, Rubinius, MRI Ruby).

Basic usage

You can activate the inliner extending your modules/classes with the Inliner module

require 'ffi-inliner'

module MyCLib
  extend Inliner
  inline 'int func_1() { return 1; }'
  inline 'int func_2() { return 2; }'

p MyCLib.func_1

class Foo
  include MyCLib


Moreover, the inliner can be configured using the block form:

inline do |builder|
  builder.c 'int func_1() { return 0; }'
  builder.use_compiler Inliner::Compilers::TCC

or using the hash form:

inline 'int func_1() { return 0; }', :use_compiler => Inliner::Compilers::TCC

How to Include header files

You can include header files using Builder#include method:

inline do |builder|
  builder.include 'stddef.h' #=> produce #include <stddef.h>

By default Builder#include use the “bracket” form. If you want to add headers using the quoted form, pass :quoted => true as optional argument:

inline do |builder|
  builder.include 'myheader.h', :quoted => true #=> produce #include "myheader.h"

How to link against custom libraries

You can link your inline C against custom libraries using Builder#library:

inline do |builder|
  builder.library 'pthreads', 'libm'

Wrap C++ code (experimental)

Using the inliner you can even link to C++ code. The trick is to use extern “C” linkage to wrap C++ inside C. When using GPlusPlus (g++) compiler, the inliner encapsulates your C code in a extern “C” block.

require 'ffi-inliner'
 module Foo
   extend Inliner
   inline do |builder|
     builder.use_compiler Inliner::Compilers::GPlusPlus
     builder.c_raw <<-code
       #include <iostream>
       #include <string>
       using namespace std;
       class Greeter  {
           string say_hello();
       Greeter::Greeter() { };
       string Greeter::say_hello() {
         return "Hello foos!";
       code 'char *' => 'string'
       builder.c <<-code
         const char* say_hello()
           Greeter greeter;
           return greeter.say_hello().c_str();

p Foo.say_hello #=> "Hello foos!"

Something went wrong with that request. Please try again.