【发布时间】:2021-09-03 16:27:39
【问题描述】:
我正在尝试为结构创建通用序列化方案。在类似thread 上给出的答案之后,我有以下设置:
#[repr(packed)]
struct MyStruct {
bytes: [u8; 4]
}
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
::std::slice::from_raw_parts(
(p as *const T) as *const u8,
::std::mem::size_of::<T>(),
)
}
fn main() {
let s = MyStruct { bytes: [0u8, 1u8, 2u8, 3u8].to_owned() };
let bytes: &[u8] = unsafe { any_as_u8_slice(&s) };
println!("{:?}", bytes);
}
输出:
[0, 1, 2, 3]
这很好用,但是它没有考虑像Vec<u8> 这样动态调整大小的结构成员,并且它们的大小需要在运行时确定。理想情况下,我想将Vec<u8> 中的每个元素编码为字节,并添加一个前缀来指示要读取的字节数。
目前我有这个:
#[repr(packed)]
struct MyStruct {
bytes: Vec<u8>
}
unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
::std::slice::from_raw_parts(
(p as *const T) as *const u8,
::std::mem::size_of::<T>(),
)
}
fn main() {
let s = MyStruct { bytes: [0u8, 1u8, 2u8, 3u8].to_vec() };
let bytes: &[u8] = unsafe { any_as_u8_slice(&s) };
println!("{:?}", bytes);
}
输出:
[208, 25, 156, 239, 136, 85, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0]
我假设上面的输出引用了某种指针,但我不确定。
目前,bincode crate 与serde crate 一起执行此操作,但它将向量的长度序列化为usize。我宁愿指定这个并将长度编码为u8,如this thread 中所述。不幸的是,这里最好的解决方案是重写 Bincode 库,这让我寻找任何替代解决方案。
编辑
使用serde 和bincode 实现:
use serde::{Serialize};
#[derive(Clone, Debug, Serialize)]
struct MyStruct {
bytes: Vec<u8>
}
fn main() {
let s = MyStruct { bytes: [0u8, 1u8, 2u8, 3u8].to_vec() };
let bytes = bincode::serialize(&s).unwrap();
println!("{:?}", bytes);
}
输出:
[4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3]
想要的输出:
[4, 0, 1, 2, 3]
【问题讨论】:
-
@kmdreko 那太好了,但我不知道如何更改选项。我编辑了帖子,你能告诉我在哪里可以更改配置吗?