FFI in Rust allows you to call functions declared in external libraries (e.g., C/C++) and export Rust functions for external use. This is done using the extern keyword. Requirements:
unsafe declaration;i32, u64, etc.);Example wrapper:
extern "C" { fn abs(input: i32) -> i32; } fn main() { unsafe { println!("{}", abs(-5)); } }
You can export a function from Rust for use in C like this:
#[no_mangle] pub extern "C" fn sum(a: i32, b: i32) -> i32 { a + b }
Question: Does Rust guarantee that if you wrap a C function call in unsafe, everything will work correctly in terms of thread safety and handling UB?
Answer: No! unsafe is a promise to the compiler that you are vouching for the correctness of all safety requirements (aliasing, thread safety, memory access). Rust does not check the code inside C. For example, race conditions or UB in the library code can "break" the runtime of the Rust program. Even if Rust code compiles, actual execution can lead to crashes.
History
long and i64 matched, but it turned out that sizes didn’t match on other platforms — incorrect memory reads led to bugs in calculations.History
History
In a client-server Rust product, a module accessed a C library without considering multi-thread safety. The library was not thread-safe, and Rust programs accessed it from different threads simultaneously, resulting in crashes and data corruption.