gpt4 book ai didi

rust - 为什么复制 C 对无符号整数的 fread 的通用函数总是返回零?

转载 作者:行者123 更新时间:2023-11-29 08:02:50 25 4
gpt4 key购买 nike

我正在尝试从 16 位体系结构中读取二进制 16 位机器指令(这里的确切性质无关紧要),然后将它们作为十六进制值打印出来。在 C 中,我发现这很简单,方法是使用 fread 函数将 16 位读入 uint16_t

我想我会尝试在 Rust 中复制 fread。如果我能提前知道正在读入的变量的确切大小,这似乎是相当微不足道的,而且我已经专门为 16 位工作了。

我决定尝试使 fread 函数对各种内置无符号整数类型具有通用性。为此,我想出了以下函数,使用了 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)
}

问题是,当我在 main 函数中调用它时,我似乎总是返回 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(())
}

在我看来,我似乎从未从文件中读取任何内容,因此该函数总是只返回它应该读取的字节数。我显然没有在这里正确使用某些东西,但老实说我不确定我做错了什么。

如果重要的话,这是在 Windows 的 Rust 1.26 稳定版上编译的。

我做错了什么,我应该做些什么来复制 fread?我意识到这可能是 XY 问题的一个例子(因为几乎可以肯定有更好的 Rust 方法从文件中重复读取一些字节并将它们打包成一个无符号整数),但我真的很好奇我是什么我在这里做错了。

最佳答案

你的问题是这一行:

let mut buf = Vec::with_capacity(element_count * type_size);

创建一个零长度 向量,即使它为element_count * type_size 字节分配内存。因此,您要求 stream.read_exact 读取零字节。解决此问题的一种方法是将上面的行替换为:

let mut buf = vec![0; element_count * type_size];

旁注:当读取成功时,bytes_read 收到您期望读取的字节数,而不是您实际读取的字节数。您可能应该使用 std::mem::size_of_val (buf_slice) 来获取真实的字节数。

关于rust - 为什么复制 C 对无符号整数的 fread 的通用函数总是返回零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50479712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com