cimpl
cimpl is a crate that ensures that the signatures of the functions in C you're implementing matches what C expects.
Why is this useful?
Lets say you have a library in C that requires you to write primitives for it to build up on,
void ;
Now this can be implemented in Rust using your usual C-FFI #[no_mangle] way although it doesn't guarantee any signature changes that may happen in the libraries requirements tomorrow. This results in complete undefined behavior (example: if it changes to void foo(uint32_t* fill_me) tomorrow you could be overflowing buffers 🚨🚨🚨). To ensure against C library fragility at compiletime, cimpl guarantees signature safety as long as the header files for the implementation can be generated at compile-time.
How to use?
build.rs changes
At build time it's required to add the cimpl post-processing step to ensure type definitions can be added into your autogenerated file.
write_all.unwrap;
Before
extern "C"
After
pub type __cimpl_foo = fn ;
extern "C"
Implementation
pub extern "C"
This generates the following:
TODOs
- Create a nicer macro like
deriveto match withbind, this allows extern "C" function implementations to not be done at compile time, however this is likely a bug and requires design reconsiderations - Tests! I'm not too familiar with
proc-macrosto know how to do this without