三个必须显式定义的契约

  1. 内存布局:#[repr(C)] 与对齐保证。
  2. 生命周期:谁分配、谁释放、何时失效。
  3. 错误语义:错误码与可恢复性边界。

最小安全接口

#[repr(C)]
pub struct Buffer {
    pub ptr: *const u8,
    pub len: usize,
}

#[no_mangle]
pub extern "C" fn process(input: Buffer, out: *mut Buffer) -> i32 {
    // 返回0表示成功,非0为错误码
    0
}

工程建议

  • 跨边界只传 POD 结构,复杂对象留在 Rust 内部。
  • 为每个导出函数写 C 侧模糊测试样例。
  • 开启 AddressSanitizer/UBSan 做集成测试。

小结

FFI 的性能上限由零拷贝决定,可靠性下限由契约决定。契约写清楚,性能和稳定性才能同时拿到。