我的函数save_vec
出现问题,使用mmap将向量保存到磁盘。它创建的文件大小合适,但当我检查其内容时(使用hexdump
),它只是全部为零。 mmap
正在使用MAP_SHARED
而不是私有,所以假设我的copy_nonoverlapping
电话出现问题。
fn save_vec<T: Encodable + Debug + Copy>(path: &str, v: &Vec<T>) -> Option<String> {
println!("save_vec");
let mut encoded: Vec<u8> = bincode::encode(v, SizeLimit::Infinite).unwrap();
let len = encoded.len();
println!("encoded = {:?}", encoded);
println!("len = {:?}", len);
let file = match OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(path) {
Ok(f) => f,
Err(err) => return Some("cannot create file".to_string())
};
file.set_len(len as u64);
let fd = file.as_raw_fd();
unsafe {
let mmap_len = len as libc::size_t;
let prot = libc::PROT_READ | libc::PROT_WRITE;
let flags = libc::MAP_SHARED;
let ptr = libc::mmap(0 as *mut libc::types::common::c95::c_void, mmap_len, prot, flags, fd, 0);
if ptr == libc::MAP_FAILED {
return Some("mmap fail".to_string())
}
let byte_ptr: *const u8 = mem::transmute(ptr);
let encoded_ptr: *mut u8 = encoded.as_mut_ptr();
ptr::copy_nonoverlapping(byte_ptr, encoded_ptr, len);
libc::munmap(ptr, len as u64);
println!("byte_ptr={:?}", byte_ptr);
}
None
}
答案 0 :(得分:2)
你可能被last-minute change to the argument order of ptr::copy and friends咬了。具体来说,这部分代码:
let byte_ptr: *const u8 = mem::transmute(ptr); // Why is this const?
let encoded_ptr: *mut u8 = encoded.as_mut_ptr(); // Why is this mutable?
ptr::copy_nonoverlapping(byte_ptr, encoded_ptr, len);
编译器实际上给了你一些错误的指示,因为你需要&#34;指向数据源的 mutable 指针。这没有任何意义 - 我们只是从那个片段中读取。目的地是不变的,这意味着我们无法改变它。
这是我运行的完整代码:
extern crate libc;
use std::{mem,ptr};
use std::fs::OpenOptions;
use std::os::unix::io::AsRawFd;
fn save_vec(path: &str, v: &[u8]) -> Result<(), String> {
let len = v.len();
let f =
OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(path);
let file = try!(f.map_err(|_| "cannot create file".to_string()));
file.set_len(len as u64).unwrap();
let fd = file.as_raw_fd();
unsafe {
let mmap_len = len as libc::size_t;
let prot = libc::PROT_READ | libc::PROT_WRITE;
let flags = libc::MAP_SHARED;
let ptr = libc::mmap(0 as *mut libc::types::common::c95::c_void, mmap_len, prot, flags, fd, 0);
if ptr == libc::MAP_FAILED {
return Err("mmap fail".to_string())
}
let byte_ptr: *mut u8 = mem::transmute(ptr);
let encoded_ptr: *const u8 = v.as_ptr();
ptr::copy_nonoverlapping(encoded_ptr, byte_ptr, len);
libc::munmap(ptr, len as u64);
}
Ok(())
}
fn main() {
save_vec("dump", b"hello").unwrap();
}