我正在尝试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中完成,还是应该切换到更安全但更慢的复制操作?
答案 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);
(然后当然处理所有其他不安全的事情。)