In this lesson, you will learn how to maintain ABI compatibility by mapping C primitive types to their exact Rust counterparts using the libc crate and core::ffi module.
When interfacing with C, using standard Rust types like i32 or usize is often correct, but it is technically dangerous because C types like int or long have sizes that vary by platform and compiler. To bridge this gap reliably, we must bypass idiomatic Rust types in favor of explicit FFI equivalents.
The libc and core::ffi Approach
The libc crate provides a canonical source of truth for platform-specific C types. For example, while c_int is generally 32-bit, c_long varies between 32 and 64 bits depending on the underlying architecture. Using libc::c_long ensures that your Rust FFI definitions match the binary interface expected by the C compiler.
For modern Rust (1.64+), we prefer core::ffi for standard types to reduce dependency overhead, while reserving libc for platform-specific extensions:
use core::ffi::{c_char, c_int, c_void};
use libc::{c_long, size_t};
#[repr(C)]
pub struct RawData {
pub id: c_int,
pub buffer: *mut c_char,
pub length: size_t,
pub flags: c_long,
}
pub extern "C" fn process_data(ptr: *const c_void) {
// Logic here...
}
Why Precision Matters
Using the wrong type—such as mapping a C long to a Rust i64 on a 32-bit system—will cause stack misalignment or data corruption when your functions are called. By using the libc or core::ffi types, you signal to the Rust compiler that these types must adhere to the layout rules of the C ABI. Always apply #[repr(C)] to your structs when they are intended to be shared across the boundary, as this prevents the Rust compiler from reordering fields for memory optimization, which would otherwise break binary compatibility.
By anchoring your definitions in these types, you transform "guesswork" into a formal contract that respects the host system’s C implementation details.
Key Takeaway: Always use core::ffi or libc primitives alongside #[repr(C)] to ensure your data layout precisely matches the host's C ABI specifications.