layout-lib

Crates.iolayout-lib
lib.rslayout-lib
version0.1.1
sourcesrc
created_at2023-08-21 07:08:10.437628
updated_at2023-08-21 07:19:56.685051
descriptionview the data layout of a struct
homepage
repositoryhttps://github.com/hangj/layout-rs
max_upload_size
id949738
size5,737
hangj (hangj)

documentation

README

layout-lib

View the data layout of a struct.

Usage

cargo add layout-lib
use layout_lib::Layout;

#[derive(Layout)]
struct A<T> {
    b: u8,
    c: u64,
    d: T,
}

#[repr(C)]
#[derive(Layout)]
struct B<T> {
    b: u8,
    c: u64,
    d: T,
}

fn main() {
    let layout = A::<Vec<i32>>::get_layout();
    println!("{}", layout);

    let layout = B::<Vec<i32>>::get_layout();
    println!("{}", layout);
}

The output will be something like this

example::A<alloc::vec::Vec<i32>> (size: 40, align: 8)
|  field   | offset |  size  |    type    |
| -------- | ------ | ------ | ---------- |
| c        | 0      | 8      | u64 (align: 8) |
| d        | 8      | 24     | alloc::vec::Vec<i32> (align: 8) |
| b        | 32     | 1      | u8 (align: 1) |

example::B<alloc::vec::Vec<i32>> (size: 40, align: 8)
|  field   | offset |  size  |    type    |
| -------- | ------ | ------ | ---------- |
| b        | 0      | 1      | u8 (align: 1) |
| c        | 8      | 8      | u64 (align: 8) |
| d        | 16     | 24     | alloc::vec::Vec<i32> (align: 8) |

As you can see, the first field of struct A in the layout is c, which is not the first declared field(b). That is because Rust does not guarantee the order of the fields in the layout be the same as the order in which the fields are specified in the declaration of the type. see The Default Representation

The offset calculation

The offset of the field is simply calculated by this macro

#[macro_export]
macro_rules! offset_of_struct {
    ($struct_name: ty, $field_name: ident) => {
        {
            let p = 0 as *const $struct_name;
            unsafe {&(*p).$field_name as *const _ as usize}
        }
    };
}
let offset = offset_of_struct!(A<Vec<i32>>, b); // 32
Commit count: 10

cargo fmt