Rust 中的 FFI 允许调用在外部库(例如 C/C++)中声明的函数,并将 Rust 函数导出。为此使用关键字 extern。要求:
unsafe 声明中;i32, u64 等);包装示例:
extern "C" { fn abs(input: i32) -> i32; } fn main() { unsafe { println!("{}", abs(-5)); } }
从 Rust 导出一个函数以供 C 使用如下:
#[no_mangle] pub extern "C" fn sum(a: i32, b: i32) -> i32 { a + b }
问题: Rust 是否保证如果将 C 函数调用包装在 unsafe 中,所有的线程安全性和 UB(未定义行为)都能正确工作?
答案: 不! unsafe 是对编译器的承诺,您自己保证所有安全性要求(别名、安全性、内存访问)的正确性。Rust 不会检查 C 内部的代码。例如,库代码中的竞争条件或 UB 可能会“破坏” Rust 程序的运行时。即使 Rust 代码编译通过,实际执行仍可能导致崩溃。
故事
long 和 i64 是匹配的,但在其他平台上发现大小不匹配 — 错误的内存读取导致了计算中的 bug。故事
故事
在客户端-服务器产品中,Rust 模块访问 C 库时没有考虑多线程安全。该库不是线程安全的,而 Rust 程序同时从不同线程访问它,导致崩溃和数据损坏。