将值切片投射到一个字节切片

时间:2015-06-09 17:05:29

标签: vector casting rust

我正在尝试API,其中调用者提供Vec<Point>他们希望我填写数据。他们可以通过with_capacity创建向量来分配空间,然后通过push(Point{...})推出其大小。然后我将使用磁盘中的字节填充底层缓冲区,根据需要切换它们的字节序表示,然后将其作为Vec<Point>提供。

这是一个函数,它使用它们的向量并用数据填充它。问题是transmute仅在类型大小相同时才有效,Point为12个字节,transmute抛弃其中11个字节。

fn read_points(&self, offset: u64, points: &mut [point::Point]) {
    let mut file = self.handle.borrow_mut();
    file.seek(SeekFrom::Start(offset)).unwrap();

    // bleep bloorp. danger!
    let points_buf : &mut [u8] = unsafe { mem::transmute(points) };
    file.read(points_buf).unwrap();

    // should take the 12 bytes and do the endian swaps
    for mut chunk in points_buf.chunks_mut(point::POINT_SIZE) {
        let point = point::buf_to_point(chunk);
        let buf : &mut [u8] = &mut chunk;
        point::fill_buf(buf, point.timestamp, point.value);
    }
}

这个API可以在Rust中完成,还是应该切换到更安全但更慢的复制操作?

1 个答案:

答案 0 :(得分:0)

&mut [T]的内存表示形式为(*mut T, usize),其中usize是切片中T个元素的数量,而不是字节数。因此,转换20个点的切片可以得到20个字节的切片。

您必须计算正确的字节数:

let n_bytes = points.len() * std::mem::size_of::<Point>();
let points_buf = std::slice::from_raw_parts_mut(points.as_mut_ptr(), n_bytes);

(然后当然处理所有其他不安全的事情。)