zerocopy
Крейт zerocopy (від Fuchsia) надає трейти та макроси для безпечного перетворення між послідовностями байтів та іншими типами.
use zerocopy::{Immutable, IntoBytes};
#[repr(u32)]
#[derive(Debug, Default, Immutable, IntoBytes)]
enum RequestType {
#[default]
In = 0,
Out = 1,
Flush = 4,
}
#[repr(C)]
#[derive(Debug, Default, Immutable, IntoBytes)]
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має типи для числових примітивів з урахуванням порядку байтів.- Запустіть приклад із
cargo runуsrc/bare-metal/useful-crates/zerocopy-example/. (Він не працюватиме на Rust Playground через залежність від крейту.)