In the last example, we had a callback that listened for a single int. What happens though if we want to listen out for a complex object from the external library (for example, a structure)? We can't return a structure, but we can have a Rust object that can be mapped to the callback.
It is a slightly more complex affair than for a synchronous callback:
- Create the structure that will map to the external structure we're interested in:
#[repr(C)] // this is a name used within the extern in (2) struct MyObject { a: i32, // and anything else you want to get back from the library // just make sure you add them into the call back }
- Create the callback; result is a pointer to the mutable myobject:
extern "C" fn callback(result: *mut MyObject, a: i32) { unsafe { (*result).a = a; } }
- Create the extern functions to the library:
#[link(name="external_lib")] extern { fn register_callback(result: mut MyObject, cback: extern fn(mut MyObject, i32)); fn start_callback(); }
- Create the calling code:
fn main() { // we need to create an object for the callback let mystruct = Box::new (MyObject{a: 5i32}); unsafe { register_callback(&mut *mystruct, callback); start_callback(); } }