Expand description
Rust bindings for libffi.
The C libffi library provides two main facilities: assembling calls
to functions dynamically, and creating closures that can be called
as ordinary C functions. In Rust, the latter means that we can turn
a Rust lambda (or any object implementing Fn/FnMut) into an
ordinary C function pointer that we can pass as a callback to C.
The easiest way to use this library is via the
high layer module, but more flexibility (and
less checking) is provided by the middle and
low layers.
§Usage
Building libffi will build lifbffi-sys, which will in turn build the libffi C library from github, which requires that you have a working make, C compiler, automake, and autoconf first. It’s on crates.io, so you can add
[dependencies]
libffi = "5.0.0"This crate depends on the libffi-sys crate, which by default
attempts to build its own version of the C libffi library. In order to
use your system’s C libffi instead, enable this crate’s system
feature in your Cargo.toml:
[features]
libffi = { version = "5.0.0", features = ["system"] }See the libffi-sys documentation for more information about how it
finds C libffi.
This crate supports Rust version 1.78 and later.
§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
highlayer provides safe(?) and automatic marshalling of Rust closures into C function pointers. - The
middlelayer provides memory-managed abstractions for assembling calls and closures, but is unsafe because it doesn’t check argument types. - The
lowlayer makes no attempts at safety, but provides a more idiomatically “Rusty” API than the underlying C library. - The
rawlayer is a re-export of thelibffi-syscrate, a direct mapping of the C libffi library into Rust, generated by 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).
§Examples
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.call(6, 7));Modules§
- high
- High layer providing automatic marshalling of Rust closures as C function pointers.
- low
- A low-level wrapping of libffi, this layer makes no attempts at safety, but tries to provide a somewhat more idiomatic interface.
- middle
- Middle layer providing a somewhat safer (but still quite unsafe) API.
- raw
- Raw definitions imported from the C library (via bindgen).
Macros§
- ffi_
call - Performs a dynamic call to a C function.