2 个版本

0.1.1 2023年8月21日
0.1.0 2023年8月21日

#2789Rust 模式

MIT 许可证

7KB
78

layout-lib

查看结构体的数据布局。

用法

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);
}

输出将类似于这样

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) |

如你所见,布局中结构体 A 的第一个字段是 c,这并不是第一个声明的字段(b)。这是因为 Rust 不保证布局中字段的顺序与类型声明中字段指定的顺序相同。参见 默认表示法

偏移量计算

字段的偏移量简单地通过这个宏来计算

#[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

依赖项

~300–760KB
~18K SLoC