我正在尝试从16位体系结构中读取二进制16位机器指令(这里与此无关),并将其打印回十六进制值。在C中,我通过使用
fread
函数将16位读入
uint16_t
.
我想我会尝试复制
弗雷德
生锈了。如果我能提前知道正在被读取的变量的确切大小,并且我已经将其专门用于16位,那么这似乎是相当微不足道的。
我决定我要尝试
弗雷德
各种内置无符号整数类型的通用函数。为此,我使用num-crate中的一些特性提出了以下功能:
fn fread<T>(
buffer: &mut T,
element_count: usize,
stream: &mut BufReader<File>,
) -> Result<usize, std::io::Error>
where
T: num::PrimInt + num::Unsigned,
{
let type_size = std::mem::size_of::<T>();
let mut buf = Vec::with_capacity(element_count * type_size);
let buf_slice = buf.as_mut_slice();
let bytes_read = match stream.read_exact(buf_slice) {
Ok(()) => element_count * type_size,
Err(ref e) if e.kind() == std::io::ErrorKind::UnexpectedEof => 0,
Err(e) => panic!("{}", e),
};
*buffer = buf_slice
.iter()
.enumerate()
.map(|(i, &b)| {
let mut holder2: T = num::zero();
holder2 = holder2 | T::from(b).expect("Casting from u8 to T failed");
holder2 << ((type_size - i) * 8)
})
.fold(num::zero(), |acc, h| acc | h);
Ok(bytes_read)
}
问题是,当我在主函数中调用它时,我似乎总是
0x00
退出,但函数返回的读取字节数始终为2,因此程序进入无限循环:
extern crate num;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::Read;
fn main() -> Result<(), std::io::Error> {
let cmd_line_args = std::env::args().collect::<Vec<_>>();
let f = File::open(&cmd_line_args[1])?;
let mut reader = BufReader::new(f);
let mut instructions: Vec<u16> = Vec::new();
let mut next_instruction: u16 = 0;
fread(&mut next_instruction, 1, &mut reader)?;
let base_address = next_instruction;
while fread(&mut next_instruction, 1, &mut reader)? > 0 {
instructions.push(next_instruction);
}
println!("{:#04x}", base_address);
for i in instructions {
println!("0x{:04x}", i);
}
Ok(())
}
在我看来,我从未从文件中读取过任何内容,所以函数总是返回它应该读取的字节数。显然我在这里没有正确地使用某些东西,但我真的不确定我做错了什么。
这是在Rust 1.26上编译的,如果这很重要的话,它是为Windows稳定的。
我做错了什么,我应该做什么不同的复制
弗雷德
?我知道这可能是xy问题的一个例子(几乎可以肯定,有一种更好的方法可以从文件中反复读取一些字节,然后将它们打包成一个无符号整数),但是我真的很好奇我在这里做了什么错误。