libffi 0.1.2

Rust bindings for libffi
docs.rs failed to build libffi-0.1.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: libffi-3.2.0

libffi-rs

Rust bindings for libffi.

Warning

This library is experimental/unstable and shouldn’t be used for anything yet. You probably can’t even build it as-is, but if it does something you need then we should talk.

Purpose

Libffi provides two main facilities:

  • Assembling calls to functions dynamically.
  • Creating closures that can be called as ordinary C functions.

The former is useful mostly for implementing FFIs for untyped languages; this library provides some support in the middle and low layers, but I’m not sure how useful it is. The latter can be used to interface between higher-order languages and C by making closures from the higher-order language callable as C function pointers. In Rust, this means that we can now, for example, pass a lambda as a callback to a C function.

Most users are likely interested in the high layer, which provides the easiest interface to the closure facility.

Organization

This library is organized in four layers, each of which attempts to provide more safety and a simpler interface than the next layer down. From top to bottom:

  • The high layer provides safe(?) and automatic marshalling of Rust closures into C function pointers.

  • The middle layer provides memory-managed abstractions for assembling calls and closures, but is unsafe because it doesn’t check argument types.

  • The low layer makes no attempts at safety, but provides a more idiomatically “Rusty” API than the underlying C library.

  • The raw layer is a direct mapping of the C libffi library into Rust, generated by Rust Bindgen.

It should be possible to use any layer without dipping into lower layers (and it will be considered a bug to the extent that it isn’t).

Example

In this example, we convert a Rust lambda containing a free variable into an ordinary C code pointer. The type of fun below is &extern "C" fn(u64, u64) -> u64.

use libffi::high::Closure2;

let x = 5u64;
let f = |y: u64, z: u64| x + y + z;

let closure = Closure2::new(&f);
let fun     = closure.code_ptr();

assert_eq!(18, fun(6, 7));

Building

I’m writing this section to document my build process.

  • Installed pkg-config: brew install pkg-config

  • Installed libffi 3.2.1 (rather than OS X system libffi, which is old)

    • brew install autoconf automake
  • Installed bindgen 0.16