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

标签 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));

在这种形式下无效(不能使用数组签名)。

最佳答案

如果你想从原始指针中获取切片,使用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),或者如果您不不要使用#[repr(C)],你写入vector的数据很可能在另一台机器上被当作垃圾读取(甚至是#[repr(C)] 有时可能无法解决这个问题,据我所知)。

关于rust - 如何从原始指针获取数组或切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55695988/

相关文章:

c# - 高效 key 生成类

C#,是否可以在没有副本的情况下将 byte* 转换为 byte[]?最快的方法是什么?

types - 如何为原始指针实现 `Default`?

generics - Rust:从(仅)<T> 不同的函数返回通用结构

rust - 将克隆添加到防 rust 液体模板

android-ndk - 无法将库从 Windows 交叉编译到 Android

rust - DRY for Rust 条件编译功能

rust - 将数据和指向该数据的可变指针存储在结构中是否安全?

rust - 不安全代码中可变引用的别名是否正确?

segmentation-fault - 在实现两个段错误的类型上从特征 A 转换为特征 B