I am struggling with passing a callback through a FFI, to a library
that I don’t control. The Rust version of the C interface looks like
this, generated by bindgen:
extern "C" {
pub fn raptor_parser_set_statement_handler(
parser: *mut raptor_parser,
user_data: *mut ::std::os::raw::c_void,
handler: raptor_statement_handler,
);
}
The library expects a handler that looks like this:
void
statement_handler(void* user_data, const raptor_statement* statement)
{
/* do something with the statement */
}
So far I have a function like this as the statement handler.
extern "C" fn statement_handler(user_data:*mut c_void,
statement: *mut raptor_statement){
}
My thought was to pass a pointer to an object through user_data; this
seems to be the approach that the rustonomicon suggests:
https://doc.rust-lang.org/nomicon/ffi.html#targeting-callbacks-to-rust-objects
I have managed to achieve this with my own Parser
struct, using this
piece of hieroglyphics.
let parser_ptr: *mut c_void = &mut parser as *mut _ as *mut c_void;
let parser:&mut Parser = &mut *(user_data as *mut Parser);
This actually (seemed) to work. But I really want to pass a
pointer to a ParserHandler
which is a trait. Then, client users of
my library can implement the ParserHandler
. ParserHandler
will be
called multiple times.
I have found a wide variety of solutions (double Box
ing for
example), but have failed to get them to work. Probably because I am
working at a “cut-and-paste” code level as I really don’t understand
much of what I am doing (I am experienced at neither Rust nor C).
Can anyone help with a solution.