如何从原始指针获取数组或切片?

时间:2014-11-26 13:37:01

标签: rust unsafe

我可以以某种方式从std::ptr::read获取数组吗?

我想做一些接近的事情:

let mut v: Vec<u8> = ...
let view = &some_struct as *const _ as *const u8;
v.write(&std::ptr::read<[u8, ..30]>(view));

在此表单中无效(无法使用数组签名)。

1 个答案:

答案 0 :(得分:11)

如果要从原始指针获取切片,请使用std::slice::from_raw_parts()

let slice = unsafe { std::slice::from_raw_parts(some_pointer, count_of_items) };

如果要从原始指针获取可变片,请使用std::slice::from_raw_parts_mut()

let slice = unsafe { std::slice::from_raw_parts_mut(some_pointer, count_of_items) };

您确定要read()吗?如果没有特别小心,它将对带有析构函数的结构造成灾难。此外,read()不会从指向字节的指针读取某些指定类型的值。它只读取指针后面一个类型的值(例如,如果它是*const u8,那么read()将读取一个字节)并返回它。

如果您只想将结构的字节内容写入向量,则可以从原始指针获取切片:

use std::mem;
use std::io::Write;

struct SomeStruct {
    a: i32,
}

fn main() {
    let some_struct = SomeStruct { a: 32 };

    let mut v: Vec<u8> = Vec::new();
    let view = &some_struct as *const _ as *const u8;
    let slice = unsafe { std::slice::from_raw_parts(view, mem::size_of::<SomeStruct>()) };
    v.write(slice).expect("Unable to write");

    println!("{:?}", v);
}

这会使您的代码依赖于平台,甚至依赖于编译器:如果您在结构中使用可变大小的类型(例如isize / usize),或者如果您不使用{{1你写入向量的数据很可能在另一台机器上被读作垃圾(据我记得,甚至#[repr(C)]有时也不会解除这个问题。)