Given these two definitions:
#[repr(C)] pub struct Ihandle { _private: [u8; 0] }
pub type Icallback = extern fn(ih: *mut Ihandle) -> i32;
I need to pass an Icallback
to an extern C function.
I know that I can declare a "global" function and pass that, but I need the function to encapsulate some local state. For that of course I could use a closure, but a closure isn't compatible with a function and I can't work out how to do it.
Here's an extract from the code that doesn't work:
struct App { ... }
impl App {
...
fn make_bindings(&mut self) {
IUP.set_callback(self.main_ok_button, "ACTION",
|ih: Ihandle| self.on_ok());
}
fn on_ok(&mut self) -> i32 {
// do something GUI
iup::DEFAULT
}
...
Here's the error:
--> src/main.rs:63:26
|
63 | |ih: Ihandle| self.on_ok());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure
|
= note: expected fn pointer `extern "C" fn(*mut iup::global::Ihandle) -> i32`
found closure `[closure@src/main.rs:63:26: 63:52 self:_]`
And here'a an extract that shows the set_callback
method:
pub fn set_callback(&self, ih: *mut Ihandle, name: &str, func: Icallback) -> Icallback {
(self._setcallback)(ih, c_from_str(&name), func)
}
And for "completeness" c_from_str
:
fn c_from_str(s: &str) -> *const c_char {
CString::new(s).unwrap().into_raw()
}
I've seen other rust bindings that achieve the effect I want but I can't understand the code, it uses macros and is just too advanced for me.