30

私の知る限り、Rust コンパイラは、構造体の各フィールドにパック、並べ替え、およびパディングを追加できます。必要な場合、正確なメモリ レイアウトを指定するにはどうすればよいですか?

C# ではStructLayout属性があり、C/C++ ではさまざまなコンパイラ拡張機能を使用できました。期待される値の位置のバイト オフセットを確認することで、メモリ レイアウトを確認できました。

正確なメモリ レイアウトを必要とするカスタム シェーダーを使用する OpenGL コードを記述したいと考えています。パフォーマンスを犠牲にせずにこれを行う方法はありますか?

4

3 に答える 3

36

FFI ガイドで説明されているように、構造体に属性を追加して、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
于 2014-10-09T06:30:57.183 に答える