WeaveFFI: write safe Rust, get a stable C ABI and bindings for 11 languages.
This is the single crate a Rust producer depends on. Annotate an ordinary
module with [macro@module], tag the items you want to export, and call
[export_runtime!] once. The [macro@module] expansion emits the
#[no_mangle] extern "C" thunks that the generated language bindings call,
marshalling every argument and result through the audited [abi] runtime so
you never write unsafe glue by hand.
#[weaveffi::module]
pub mod calculator {
/// Add two integers.
#[weaveffi::export]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
/// Divide, reporting division by zero through the ABI's error channel.
#[weaveffi::export]
pub fn div(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err("division by zero".to_string());
}
Ok(a / b)
}
}
// Expose the fixed runtime surface (memory/error/cancel helpers) once.
weaveffi::export_runtime!();
The same annotated source is what weaveffi generate path/to/lib.rs reads to
emit the IDL, header, and bindings, so the producer and the bindings cannot
drift: they are two views of one parse.
What you get
- [
macro@module] - the driver attribute on an exportedmod. - [
macro@export] - export a function (async fnis asynchronous; aResult-returning fn is fallible). - [
macro@record] - a by-value struct with generated create/getters. - [
macro@enumeration] - a#[repr(i32)]C-style enum. - [
macro@callback] / [macro@listener] - a callback and an event listener. - [
macro@cancellable] - mark anasync fnas accepting a cancel token; [macro@builder] - opt a record into a fluent builder. - [
abi] - the C ABI runtime: the error struct, memory helpers, the marshalling converters the expansion calls, and [export_runtime!].