These are the most simple callback objects. They consist of a single (function) pointer, that is, the address of the (beginning of the) code that is to be called.
In Rust, this is the family of
fn(...) -> _types.
To avoid (very bad) bugs when mixing calling conventions (ABIs), Rust includes the ABI within the type of the function pointer, granting additional type-level safety. When dealing with C, the calling convention that matches C's is almost always
extern "C"and is never
When unspecified, the calling convention defaults to
extern "Rust", which is different from
This is why all function pointers involved in FFI need to be
extern-annotated. Forgetting it results in code that triggers Undefined Behavior (and traditional FFI fails to guard against it)⚠️
In C, these are written as
ret_t (*name)(function_args), where
nameis the name of a variable or parameter that has the function pointer type, or the name of the type being type-aliased to the function pointer type.
So, for instance,
#[ffi_export] fn call ( ctx: *mut c_void, cb: unsafe extern "C" fn(ctx: *mut c_void), )
void call ( void * ctx, void (*cb)(void * ctx) );
fn pointer cannot possibly be NULL!
This means that when
NULL-able function pointers are involved, forgetting to
Option-wrap them can lead to Undefined Behavior. Luckily, this is something
that is easily caught by
::safer_ffi's sanity checks.