I'm trying to make a Rust binding to nbdkit without much luck. I need to make a .so file, which is easy. The .so file must have a public function called plugin_init, also easy. However this function must return a pointer to a C-compatible struct containing a mix of strings and function pointers (that the C main program will later call).
I came up with:
#[repr(C)] pub struct NBDKitPlugin { _struct_size: uint64_t, _api_version: c_int, _thread_model: c_int, name: *const c_char, longname: Option<*const c_char>, version: Option<*const c_char>, description: Option<*const c_char>, load: Option<extern fn ()>, unload: Option<extern fn ()>, config: Option<extern fn ()>, // XXX config_complete: Option<extern fn () -> c_int>, config_help: Option<*const c_char>, open: extern fn (c_int) -> *mut c_void, close: Option<extern fn (*mut c_void)>, } and a plugin_init function:
extern fn hello_load () { println! ("hello this is the load method"); } struct MyHandle { } extern fn hello_open (readonly: c_int) -> *mut c_void { println! ("hello, this is the open method"); let mut h = MyHandle {}; let vp: *mut c_void = &mut h as *mut _ as *mut c_void; return vp; } #[no_mangle] pub extern fn plugin_init () -> *const NBDKitPlugin { println! ("hello from the plugin"); let plugin = Box::new (NBDKitPlugin { _struct_size: mem::size_of::<NBDKitPlugin>() as uint64_t, _api_version: 2, _thread_model: 3, name: CString::new("hello").unwrap().into_raw(), longname: None, version: None, description: None, load: Some (hello_load), unload: None, config: None, config_complete: None, config_help: Some (CString::new("my config_help here").unwrap().into_raw()), open: hello_open, close: None, }); return Box::into_raw(plugin); } Apart from leaking memory, this partially works. The integers and strings are seen from C OK. However the function pointers don't work at all. They are completely bogus and seem to occupy more space than a raw pointer so I suppose that I'm exposing a "fat" Rust pointer.
There seems very little documentation on this topic that I can find. Help.