我正在将一个低延迟的实时应用程序移植到Rust.从本质上讲,我希望在不复制的情况下尽可能多地执行操作.目前内存分配的一个主要来源是网络堆栈.每次接收或发送包时,都会在幕后进行大量复制,以强制执行Rust struct 中的字节并从中检索字节.我不想再这么做了.
从本质上讲,我希望能够将包从/转换为字节并传输它.下面是一个非工作的示例代码,它说明了我想要做的事情.
#[repr(C, align(4))]
#[derive(Debug)]
struct Content {
first: u8,
padding: [u8; 3]
}
#[repr(C, align(4))]
#[derive(Debug)]
struct Packet {
header_id: u16,
header_padding: [u8; 2],
// This is another pointer I want it to be located after header_padding
content: Box<[Content]>,
}
#[derive(Debug)]
struct ParsedPacket {
content_length: usize,
// The box below should directly reference the original u8 bytes without copying
packet: Box<Packet>,
}
unsafe fn buf_to_packet(bs: Box<[u8]>) -> Option<Box<ParsedPacket>> {
// How to implement this
// First 4 bytes are the header
// The rest must be 4 byte multiple and each 4 byte is a Content struct
// So from the length of the boxed slice we can infer the content_length
todo!()
}
unsafe fn packet_to_buf(bs: ParsedPacket) -> Box<[u8]> {
todo!()
}
fn main() {
let bytes = vec![
// Header
0, 23, 0, 0,
// Content 0
0, 0, 0, 0,
// Content 1
1, 0, 0, 0,
// Content 2
0, 0, 0, 0
].into_boxed_slice();
let packet = unsafe { buf_to_packet(bytes) };
println!("{:?}", content);
}
这有两个问题.铁 rust 要求内容是盒装的切片.这主要是因为它不一定位于 struct 本身,而可能位于其他地方.此外,盒装切片还包含它自己的关于长度的簿记.我想我需要自己做长度的记账.但我不知道如何在不使用盒装切片的情况下添加具有动态长度的 struct 成员.
我当然愿意使用不安全来做这件事.但我没有使用铁 rust 的经验,所以我不知道如何才能真正实现这一点.
从本质上说,我在Rust中寻找的是来自C的Flexible array members.