Function libffi::low::prep_closure_mut
[−]
[src]
pub unsafe fn prep_closure_mut<U, R>(
closure: *mut ffi_closure,
cif: *mut ffi_cif,
callback: CallbackMut<U, R>,
userdata: *mut U,
code: CodePtr
) -> Result<()>
Initializes a mutable closure with a callback function and (mutable) 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 immutable userdata use prep_closure
.
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: &mut u64) { let args: *const &u64 = mem::transmute(args); *result = *userdata; *userdata += **args; } 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_mut(closure, &mut cif, callback, &mut userdata, CodePtr(add5 as *mut _)).unwrap(); assert_eq!(5, add5(6)); assert_eq!(11, add5(7)); assert_eq!(19, twice(add5, 1)); }