Function libffi::low::prep_closure_mut
source · 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<()>
Expand description
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));
}