One of Rust’s biggest selling points is how well it can interoperate with C. It’s able to call into C libraries and produce APIs that C can call into with very little fuss. However, when dealing with sufficiently complex APIs, mismatches between language concepts can become a problem. In this post we’re going to look at how to handle callback functions when working with C from Rust.
Our hypothetical library has a Widget
struct, which periodically generates events. We want to take a callback function from users that is called whenever one of these events occurs. More concretely, we want to provide this signature:
impl Widget {
fn register_callback(&mut self, callback: impl FnMut(Event)) {
// ...
}
}
Unlike Rust, C has no concept of closures. Instead it has function pointers. To put this in Rust terms, you can take fn(Event)
, but not impl FnMut(Event)
. Function pointers...