rust memory-layout

Control de diseño de memoria precisa en Rust?



memory-layout (2)

Como se describe en la guía FFI , puede agregar atributos a las estructuras para usar el mismo diseño que C:

#[repr(C)] struct Object { a: i32, // other members }

y también tiene la capacidad de empaquetar la estructura:

#[repr(C, packed)] struct Object { a: i32, // other members }

Y para detectar que el diseño de la memoria es correcto, puede inicializar una estructura y verificar que las compensaciones son correctas convirtiendo los punteros en enteros:

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

salidas:

a: 0 b: 1 c: 3

Que yo sepa, el compilador Rust puede empacar, reordenar y agregar relleno a cada campo de una estructura. ¿Cómo puedo especificar el diseño de memoria preciso si lo necesito?

En C #, tengo el atributo StructLayout , y en C / C ++, podría usar varias extensiones de compilador. Pude verificar el diseño de la memoria al verificar el desplazamiento de bytes de las ubicaciones de valor esperado.

Me gustaría escribir código OpenGL utilizando sombreadores personalizados, que necesitan un diseño de memoria preciso. ¿Hay una manera de hacer esto sin sacrificar el rendimiento?


Ya no hay to_uint . En Rust 1.0, el código puede ser:

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