Function libffi::low::prep_closure
source · pub unsafe fn prep_closure<U, R>(
closure: *mut ffi_closure,
cif: *mut ffi_cif,
callback: Callback<U, R>,
userdata: *const U,
code: CodePtr
) -> Result<()>
Expand description
Initializes a closure with a callback function and userdata.
After allocating a closure with closure_alloc
, it needs to be
initialized with a function callback
to call and a pointer
userdata
to pass to it. Invoking the closure’s code pointer will
then pass the provided arguments and the user data pointer to the
callback.
For mutable userdata use prep_closure_mut
.
Safety
The closure retains a reference to CIF cif
, so that must
still be live when the closure is used lest undefined behavior
result.
Arguments
closure
— the closure to initializecif
— the calling convention and types for calling the closurecallback
— the function that the closure will invokeuserdata
— the closed-over value, stored in the closure and passed to the callback upon invocationcode
— the closure’s code pointer, i.e., the second component returned byclosure_alloc
.
Result
Ok(())
for success or Err(e)
for failure.
Examples
use libffi::low::*;
use std::mem;
use std::os::raw::c_void;
unsafe extern "C" fn callback(_cif: &ffi_cif,
result: &mut u64,
args: *const *const c_void,
userdata: &u64)
{
let args: *const &u64 = mem::transmute(args);
*result = **args + *userdata;
}
fn twice(f: extern "C" fn(u64) -> u64, x: u64) -> u64 {
f(f(x))
}
unsafe {
let mut cif: ffi_cif = Default::default();
let mut args = [&mut types::uint64 as *mut _];
let mut userdata: u64 = 5;
prep_cif(&mut cif, ffi_abi_FFI_DEFAULT_ABI, 1, &mut types::uint64,
args.as_mut_ptr()).unwrap();
let (closure, code) = closure_alloc();
let add5: extern "C" fn(u64) -> u64 = mem::transmute(code);
prep_closure(closure,
&mut cif,
callback,
&mut userdata,
CodePtr(add5 as *mut _)).unwrap();
assert_eq!(11, add5(6));
assert_eq!(12, add5(7));
assert_eq!(22, twice(add5, 12));
}