问题描述
基本上我有一个基于 tcp 的网络协议要解析.
Essentially I have a tcp based network protocol to parse.
在 C 中,我可以将一些内存转换为我想要的类型.我怎样才能用 Rust 完成类似的事情.
In C I can just cast some memory to the type that I want. How can I accomplish something similar with Rust.
推荐答案
你也可以在 Rust 中做同样的事情.您只需要在定义结构时小心一点.
You can do the same thing in Rust too. You just have to be little careful when you define the structure.
use std::mem;
#[repr(C)]
#[packed]
struct YourProtoHeader {
magic: u8,
len: u32
}
let mut buf = [0u8, ..1024]; // large enough buffer
// read header from some Reader (a socket, perhaps)
reader.read_at_least(mem::size_of::<YourProtoHeader>(), buf.as_mut_slice()).unwrap();
let ptr: *const u8 = buf.as_ptr();
let ptr: *const YourProtoHeader = ptr as *const YourProtoHeader;
let ptr: &YourProtoHeader = unsafe { &*ptr };
println!("Data length: {}", ptr.len);
不幸的是,我不知道如何将缓冲区指定为恰好 size_of::<YourProtoHeader>()
大小;缓冲区长度必须是一个常量,但是 size_of()
调用在技术上是一个函数,所以当我在数组初始值设定项中使用它时 Rust 会抱怨.尽管如此,足够大的缓冲区也可以工作.
Unfortunately, I don't know how to specify the buffer to be exactly size_of::<YourProtoHeader>()
size; buffer length must be a constant, but size_of()
call is technically a function, so Rust complains when I use it in the array initializer. Nevertheless, large enough buffer will work too.
这里我们将指向缓冲区开头的指针转换为指向您的结构的指针.这与您在 C 中所做的相同.结构本身应该用 #[repr(C)]
和 #[pack]
属性进行注释:第一个不允许可能的字段重新排序,第二个禁用字段对齐的填充.
Here we're converting a pointer to the beginning of the buffer to a pointer to your structure. This is the same thing you would do in C. The structure itself should be annotated with #[repr(C)]
and #[pack]
attributes: the first one disallows possible field reordering, the second disables padding for field alignment.
这篇关于用 Rust 解析二进制协议的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!