我有一个未知大小的字节缓冲区,我想创建一个指向缓冲区起始内存的局部结构变量。按照我在C中所做的,我在Rust中尝试了很多不同的事情,但总是得到错误。这是我最近的尝试:
use std::mem::{size_of, transmute};
#[repr(C, packed)]
struct MyStruct {
foo: u16,
bar: u8,
}
fn main() {
let v: Vec<u8> = vec![1, 2, 3];
let buffer = v.as_slice();
let s: MyStruct = unsafe { transmute(buffer[..size_of::<MyStruct>()]) };
}
我得到一个错误:
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> src/main.rs:12:42
|
12 | let s: MyStruct = unsafe { transmute(buffer[..size_of::<MyStruct>()]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
4条答案
按热度按时间kuarbcqp1#
如果你不想把数据复制到结构体中,而是把它留在原处,你可以使用
slice::align_to
,这会创建一个&MyStruct
:这里,使用
align_to
将一些字节转换为MyStruct
是安全的,因为我们使用了repr(C, packed)
,并且MyStruct
中的所有类型都可以是任意字节。另见:
ycl3bljg2#
您可以使用raw pointers上的方法和
std::ptr
中的函数直接在适当的位置读取/写入对象。std::ptr::read
std::ptr::read_unaligned
std::ptr::write
std::ptr::write_unaligned
在您的情况下:
我鼓励您将其 Package 在一个可重用的方法中,并在尝试读取之前对源缓冲区执行长度检查。
w51jfk4q3#
我放弃了变形的东西。Rust中的
*mut
(原始指针)与C指针非常相似,所以这很容易:unsafe
标记不是开玩笑的,但我使用它的方式,我知道我的缓冲区已满,并采取适当的预防措施,涉及字节序稍后。tcomlyy64#
我目前正在使用:
当然不安全,但是很好用。