zerocopy

zerocopy Crate (來自 Fuchsia) 提供特徵和巨集,可在位元組序列和其他型別之間安全地轉換。

use zerocopy::AsBytes;

#[repr(u32)]
#[derive(AsBytes, Debug, Default)]
enum RequestType {
    #[default]
    In = 0,
    Out = 1,
    Flush = 4,
}

#[repr(C)]
#[derive(AsBytes, Debug, Default)]
struct VirtioBlockRequest {
    request_type: RequestType,
    reserved: u32,
    sector: u64,
}

fn main() {
    let request = VirtioBlockRequest {
        request_type: RequestType::Flush,
        sector: 42,
        ..Default::default()
    };

    assert_eq!(
        request.as_bytes(),
        &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]
    );
}

這不適合 MMIO (因為並非採用揮發性讀取和寫入方法),但很適合搭配使用與硬體共用的結構 (例如藉由 DMA),或透過外部介面傳送的結構。

  • FromBytes 可針對任何位元組模式有效的型別實作,因此可從不受信任的位元組序列安全地完成轉換。
  • 嘗試衍生這些型別的 FromBytes 會失敗,因為 RequestType 不會使用所有可能的 u32 值做為判別值,所以並非所有位元組模式都有效。
  • zerocopy::byteorder 的型別適用於瞭解位元組順序的數值基元。
  • 使用 src/bare-metal/useful-crates/zerocopy-example/ 下的 cargo run 執行範例 (在 Playground 中,範例會因為 Crate 依附元件而無法執行)。