Function libffi::low::prep_closure
[−]
[src]
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<()>
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)); }