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

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));
}