6.8 Unsafe Rust and Interoperability with C
While Rust enforces strict safety guarantees, sometimes you need to perform operations that the compiler cannot verify as safe.
6.8.1 Unsafe Blocks
fn main() { let mut num = 5; unsafe { let r1 = &mut num as *mut i32; // Raw pointer *r1 += 1; } println!("num = {}", num); }
Inside an unsafe
block, you can perform operations like dereferencing raw pointers. Use unsafe
blocks sparingly and encapsulate them within safe abstractions. This limits the scope of potential unsafe behavior and maintains overall program safety.
6.8.2 Interfacing with C
Rust can interface with C code using extern
blocks.
Calling C from Rust:
extern "C" { fn puts(s: *const i8); } fn main() { unsafe { puts(b"Hello from Rust!\0".as_ptr() as *const i8); } }
Calling Rust from C:
Rust code:
#![allow(unused)] fn main() { #[no_mangle] pub extern "C" fn add(a: i32, b: i32) -> i32 { a + b } }
C code:
#include <stdio.h>
extern int add(int a, int b);
int main() {
int result = add(5, 3);
printf("Result: %d\n", result);
return 0;
}
You can use tools like bindgen
to generate Rust bindings to existing C libraries, facilitating interoperability.