2014-10-09 23 views
17

Theo như tôi biết, trình biên dịch Rust được phép đóng gói, sắp xếp lại và thêm phần đệm vào mỗi trường của một cấu trúc. Làm cách nào tôi có thể chỉ định bố cục bộ nhớ chính xác nếu tôi cần?Kiểm soát bố cục bộ nhớ chính xác trong Rust?

Trong C#, tôi có thuộc tính StructLayout và trong C/C++, tôi có thể sử dụng các phần mở rộng trình biên dịch khác nhau. Tôi có thể xác minh bố cục bộ nhớ bằng cách kiểm tra độ lệch byte của các vị trí giá trị dự kiến.

Tôi muốn viết mã OpenGL sử dụng trình tạo bóng tùy chỉnh, cần bố cục bộ nhớ chính xác. Có cách nào để làm điều này mà không bị mất hiệu suất?

Trả lời

22

Như đã trình bày trong the FFI guide, bạn có thể thêm các thuộc tính để cấu trúc sử dụng cách bố trí tương tự như C:

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

và bạn cũng có khả năng để đóng gói các struct:

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

Và đối với phát hiện rằng bố trí bộ nhớ là ok, bạn có thể khởi tạo một cấu trúc và kiểm tra rằng các offset là ok bằng cách truyền con trỏ đến số nguyên:

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

kết quả đầu ra:

a: 0 
b: 1 
c: 3 
4

Không còn to_uint. Trong Rust 1.0, mã có thể là:

#[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); 
} 
Các vấn đề liên quan