據我所知,Rust編譯器可以打包,重新排序,併爲結構的每個字段添加填充。如果我需要它,我如何指定精確的內存佈局?Rust中精確的內存佈局控制?
在C#中,我有StructLayout
屬性,而在C/C++中,我可以使用各種編譯器擴展。我可以通過檢查期望值位置的字節偏移來驗證內存佈局。
我想寫自定義着色器,它需要精確的內存佈局的OpenGL代碼。有沒有辦法做到這一點,而不犧牲性能?
據我所知,Rust編譯器可以打包,重新排序,併爲結構的每個字段添加填充。如果我需要它,我如何指定精確的內存佈局?Rust中精確的內存佈局控制?
在C#中,我有StructLayout
屬性,而在C/C++中,我可以使用各種編譯器擴展。我可以通過檢查期望值位置的字節偏移來驗證內存佈局。
我想寫自定義着色器,它需要精確的內存佈局的OpenGL代碼。有沒有辦法做到這一點,而不犧牲性能?
如the FFI guide描述,您可以添加屬性結構使用相同的佈局C:
#[repr(C)]
struct Object {
a: i32,
// other members
}
,你也有收拾結構的能力:
#[repr(C, packed)]
struct Object {
a: i32,
// other members
}
而對於檢測到內存佈局正常,您可以初始化一個結構並通過將指針指向整數來檢查偏移是否正常:
#[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
現在,已經沒有to_uint
。在Rust 1.0中,代碼可以是:
#[repr(C, packed)]
struct Object {
a: i8,
b: i16,
c: i32, // other members
}
fn main() {
let obj = Object {
a: 0x1a,
b: 0x1bbb,
c: 0x1ccccccc,
};
let base = &obj as *const _ as usize;
let a_off = &obj.a as *const _ as usize - base;
let b_off = &obj.b as *const _ as usize - base;
let c_off = &obj.c as *const _ as usize - base;
println!("a: {}", a_off);
println!("b: {}", b_off);
println!("c: {}", c_off);
}