2 个版本
0.1.1 | 2023年8月21日 |
---|---|
0.1.0 | 2023年8月21日 |
#2789 在 Rust 模式
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