据我所知,Rust编译器可以对 struct 的每个字段进行打包、重新排序和添加填充.如果需要,如何指定精确的内存布局?
在C#中,我有StructLayout
属性,在C/C++中,我可以使用各种编译器扩展.我可以通过判断期望值位置的字节偏移量来验证内存布局.
我想用自定义着色器编写OpenGL代码,这需要精确的内存布局.有没有一种方法可以在不牺牲性能的情况下做到这一点?
据我所知,Rust编译器可以对 struct 的每个字段进行打包、重新排序和添加填充.如果需要,如何指定精确的内存布局?
在C#中,我有StructLayout
属性,在C/C++中,我可以使用各种编译器扩展.我可以通过判断期望值位置的字节偏移量来验证内存布局.
我想用自定义着色器编写OpenGL代码,这需要精确的内存布局.有没有一种方法可以在不牺牲性能的情况下做到这一点?
如the FFI guide所述,您可以向 struct 添加属性,以使用与C相同的布局:
#[repr(C)]
struct Object {
a: i32,
// other members
}
您还可以打包 struct :
#[repr(C, packed)]
struct Object {
a: i32,
// other members
}
为了检测内存布局是否正常,可以初始化 struct ,并通过将指针转换为整数来判断偏移是否正常:
#[repr(C, packed)]
struct Object {
a: u8,
b: u16,
c: u32, // other members
}
fn main() {
let obj = Object {
a: 0xaa,
b: 0xbbbb,
c: 0xcccccccc,
};
let a_ptr: *const u8 = &obj.a;
let b_ptr: *const u16 = &obj.b;
let c_ptr: *const u32 = &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);
}
输出:
a: 0
b: 1
c: 3