Function ffi_helpers::split_closure[][src]

pub unsafe fn split_closure<C, Args, Ret>(
    closure: &mut C
) -> (*mut c_void, C::Trampoline) where
    C: Split<Args, Ret>, 
Expand description

Splits a closure into its data part and its code part, allowing it to be used as a callback by FFI code.

Examples

use std::ffi::c_void;

let mut total = 0;

// let's define a closure which will update a total and return its new value
let mut some_closure = |n: usize| { total += n; total };

// the callback the C function is expecting
type Callback = unsafe extern "C" fn(*mut c_void, usize) -> usize;

// pretend this is some C function which will periodically call a callback,
// passing along a user-provided pointer for state.
unsafe fn some_c_function(max_value: usize, cb: Callback, user_data: *mut c_void) {
    for i in 0..max_value {
        let got = cb(user_data, i);
        println!("iteration: {}, total: {}", i, got);
    }
}

unsafe {
    // split the closure into its state section and the code section
    let (state, callback) = ffi_helpers::split_closure(&mut some_closure);

    // then pass it to the C function
    some_c_function(42, callback, state);
}

assert_eq!(total, (0..42).sum());

Safety

The returned function can only be called with the returned pointer, or a pointer to another C closure.