Interoperability

Interoperability between Rust and C code is always dependent on transforming data between the two languages. For this purposes there are two dedicated modules in the stdlib called std::ffi and std::os::raw.

std::os::raw deals with low-level primitive types that can be converted implicitly by the compiler because the memory layout between Rust and C is similar enough or the same.

std::ffi provides some utility for converting more complex types such as Strings, mapping both &str and String to C-types that are easier and safer to handle.

For #![no_std] environments, there is also core::raw that covers all the primitive types.

Rust typeIntermediateC type
StringCString*char
&strCStr*const char
()c_voidvoid
u32 or u64c_uintunsigned int
etc......

As mentioned above, primitive types can be converted by the compiler implicitly.

unsafe fn foo(num: u32) {
    let c_num: c_uint = num;
    let r_num: u32 = c_num;
}