Expand description
Provides wrappers around closures which allows them to be called through context-free unsafe bare functions.
Context-free bare functions are not needed very often, as properly designed C APIs typically allow the user to specify an opaque pointer to a context object which will be provided to the function pointer. However, this is not always the case, and may be impossible in less common scenarios, e.g. function hooking for game modding/hacking.
§Features
The crate comes with the following feature flags:
§Stable
std
(default): Usestd
features. When this is turned off, the crate is compatible withno_std
, although a global allocator must be defined.global_jit_alloc
(default): Provides theGlobalJitAlloc
ZST which defers to a global JIT allocator implementation provided either throughdefault_jit_alloc
feature or theglobal_jit_alloc!
macro.default_jit_alloc
(default): Provides a global JIT allocator implementation through thejit-allocator2
crate. Note that said crate relies on operating system APIs, so while someno_std
configurations are supported, bare metal ones will not be able to use this feature.proc_macros
: Provides thebare_hrtb
proc macro which is necessary for creating bare functions with signatures that involve higher-kinded lifetimes (i.e.for<'a, ...>
statements).
§Unstable (require a nightly compiler)
unstable
: Enable the use of unstable Rust features for aspects of the crate that benefit from them without causing any API breaks. Unstable features that can cause breaking changes when enabled are gated separately, and also enable this feature.tuple_trait
: Adds acore::marker::Tuple
bound onFnPtr::Args
. This allows downstream crates to easily integrate the library with closure-related nightly features such asunboxed_closures
andfn_traits
.c_variadic
: Adds partial (no invocation throughcall
)FnPtr
andFn*Thunk
implementations for variadic functions.coverage
: Enables support for the-C instrument-coverage
compiler flag.
§Examples
Passing a closure to a C API taking a contextless function pointer:
use closure_ffi::{BareFnMut};
// Imagine we have an foreign C API for reigstering and unregistering some callback function.
// Notably, the API does not let the user provide a context object to the callback.
unsafe extern "C" fn ffi_register_callback(cb: unsafe extern "C" fn(u32)) {
// ...
}
unsafe extern "C" fn ffi_unregister_callback(cb: unsafe extern "C" fn(u32)) {
// ...
}
#[cfg(feature = "default_jit_alloc")]
{
// We want to keep track of sum of callback arguments without using
// statics. This is where closure-ffi comes in:
let mut sum = 0; // Non-'static closures work too!
let wrapped = BareFnMut::new_c(|x: u32| {
sum += x;
});
// Safety: Here, we assert that the foreign API won't use the callback
// in ways that break Rust's safety rules. Namely:
// - The exclusivity of the FnMut's borrow is respected.
// - If the calls are made from a different thread, the closure is Sync.
// - We unregister the callback before the BareFnMut is dropped.
unsafe {
ffi_register_callback(wrapped.bare());
// Do something that triggers the callback...
ffi_unregister_callback(wrapped.bare());
}
drop(wrapped);
println!("{sum}");
}
§Credits
Modules§
- bare_
closure - Provides the
BareFnOnce
,BareFnMut
andBareFn
wrapper types which allow closures to be called through context-free unsafe bare functions. - cc
- Defines calling convention marker types for use with
BareFn
variants. - jit_
alloc - Abstractions around allocators that provide dual-mapped memory with XOR protection rules (one RW view and one RX view) suitable for emitting code at runtime.
- prelude
- Common imports required to use
closure-ffi
. - traits
- Traits that
closure-ffi
uses to power its functionality.
Macros§
- bare_
hrtb proc_macros
- Declares a wrapper type around a higher-ranked bare function which can be used with BareFn and friends.
- global_
jit_ alloc global_jit_alloc
and non-default_jit_alloc
- Defines a global
JitAlloc
implementation whichGlobalJitAlloc
will defer to.
Structs§
- Bare
FnAny - Wrapper around a
Fn
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnMut Any - Wrapper around a
FnMut
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnOnce Any - Wrapper around a
FnOnce
closure which exposes a bare function thunk that can invoke it without additional arguments. - JitAlloc
Error - Anonymous error that may be returned by
JitAlloc
implementations whenJitAlloc::alloc
orJitAlloc::release
fail. - Untyped
Bare Fn - Type-erased wrapper around a
Fn
closure which exposes a pointer to a bare function thunk. - Untyped
Bare FnMut - Type-erased wrapper around a
FnMut
closure which exposes a pointer to a bare function thunk. - Untyped
Bare FnOnce - Type-erased wrapper around a
FnOnce
closure which exposes a pointer to a bare function thunk.
Traits§
- JitAlloc
- Generic allocator providing virtual memory suitable for emitting code at runtime.
Type Aliases§
- BareFn
- Wrapper around a
Fn
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnMut - Wrapper around a
FnMut
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnMut Sync - Wrapper around a
FnMut
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnOnce - Wrapper around a
FnOnce
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnOnce Sync - Wrapper around a
FnOnce
closure which exposes a bare function thunk that can invoke it without additional arguments. - Bare
FnSync - Wrapper around a
Fn
closure which exposes a bare function thunk that can invoke it without additional arguments.