123456789_123456789_123456789_123456789_123456789_

Ruby programs can now easily call native C library functions via the FFI mechanism.

Basics: require 'ffi' and attach_function

The require 'ffi' directive will load and initialize the FFI library. You then need to use extend FFI::Library in a module you wish to attach native functions to, and finally, use attach_function to link the native C functions into the module.

Hello, World using FFI

require 'ffi'

module Hello
  extend FFI::Library
  ffi_lib FFI::Library::LIBC
  attach_function :puts, [ :string ], :int
end

Hello.puts("Hello, World")

The interesting part above is the attach_function call. It requests that a C function named puts which takes a :string argument and returns an :int, be attached to the Hello module.

The attach_function method locates the C function in a specific external library (i.e. libc in the example). To use it, you need to supply the name of the function to load, the parameter types the function takes, and the return type of the function.

Long running C functions should be declared as blocking functions by adding blocking: true to attach_function as in the following example. See the Callback chapter for a discussion of the impact of blocking: true.

Hello, Windows using FFI

require 'ffi'

module HelloWin
  extend FFI::Library

  ffi_lib 'user32'
  ffi_convention :stdcall

  attach_function :message_box, :MessageBoxA,[ :pointer, :string, :string, :uint ], :int, blocking: true
end

rc = HelloWin.message_box nil, 'Hello Windows!', 'FFI on Windows', 1
puts "Return code: #{rc}"

Using the Windows API is almost as easy as the previous example. Typically you need to tell FFI what Windows library to search via the ffi_lib method and tell FFI to use the stdcall convention used by the Windows API. The ffi_convention method tells FFI what calling convention to use.

You also need to ensure that you attach the correctly named function to your Ruby module. For all functions that take string arguments, the Windows API provides "short name" macros that expand to function names with a suffix indicating ASCII or Unicode. ANSI versions are suffixed with a "A", and Unicode versions are suffixed with a "W".

Parameter and return types

Here below there is a partial list of the types supported by FFI. For a more exhaustive list you may look at [[Types]] page.

External links

Charles Nutter's FFI announcement