Precise memory layout control in Rust?

As described in the FFI guide, you can add attributes to structs to use the same layout as C:

#[repr(C)]
struct Object {
    a: i32,
    // other members
}

and you also have the ability to pack the struct:

#[repr(C, packed)]
struct Object {
    a: i32,
    // other members
}

And for detecting that the memory layout is ok, you can initialize a struct and check that the offsets are ok by casting the pointers to integers:

#[repr(C, packed)]
struct Object {
    a: u8,
    b: u16,
    c: u32, // other members
}

fn main() {
    let obj = Object {
        a: 0xaa,
        b: 0xbbbb,
        c: 0xcccccccc,
    };

    // addr_of! used here due to unaligned references being UB: https://github.com/rust-lang/rust/issues/82523
    let a_ptr: *const u8 = std::ptr::addr_of!(obj.a);
    let b_ptr: *const u16 = std::ptr::addr_of!(obj.b);
    let c_ptr: *const u32 = std::ptr::addr_of!(obj.c);

    let base = a_ptr as usize;

    println!("a: {}", a_ptr as usize - base);
    println!("b: {}", b_ptr as usize - base);
    println!("c: {}", c_ptr as usize - base);
}

outputs:

a: 0
b: 1
c: 3

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)