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

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