gpt4 book ai didi

winapi - 为什么从 winapi 复制到我的代码中的结构定义没有相同的行为?

转载 作者:行者123 更新时间:2023-12-03 11:33:17 31 4
gpt4 key购买 nike

我正在尝试阅读 IMAGE_DOS_HEADER使用 definition of that structure 的模块来自 winapi箱。

这是我的工作代码:

let mut IDH: IMAGE_DOS_HEADER = uninitialized();
copy_nonoverlapping(library, (&mut IDH as *mut IMAGE_DOS_HEADER) as *mut c_void, size_of::<IMAGE_DOS_HEADER>());

我意识到 winapi太大了,我希望我的二进制文件小于 1 兆字节,所以我声明了 IMAGE_DOS_HEADER我自己的结构:
#[derive(Copy, Clone)]
pub struct _IMAGE_DOS_HEADER{
pub e_magic: u16,
pub e_cblp: u16,
pub e_cp: u16,
pub e_crlc: u16,
pub e_cparhdr: u16,
pub e_minalloc: u16,
pub e_maxalloc: u16,
pub e_ss: u16,
pub e_sp: u16,
pub e_csum: u16,
pub e_ip: u16,
pub e_cs: u16,
pub e_lfarlc: u16,
pub e_ovno: u16,
pub e_res: [u16; 4],
pub e_oemid: u16,
pub e_oeminfo: u16,
pub e_res2: [u16; 10],
pub e_lfanew: i32,
}

当我这样做时,结构的所有字段都会得到奇怪的值(例如: e_magic = 0x3)。

我决定在这两种情况下都将结构转换为数组,即使它们在编程上完全相同。
println!("{:?}", std::mem::transmute::<IMAGE_DOS_HEADER, [u8;0x40]>(IDH).to_vec());

对于他们俩,它都打印了:

[77, 90, 144, 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0]

这真的很奇怪。他们的字段值之间不应该有任何差异。然后我复制打印的数组并将其转换为我的结构,看看是否所有字段都正常。
let dos: [u8;0x40] = [77, 90, 144, 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0];
println!("{}", std::mem::transmute::<[u8;0x40], _IMAGE_DOS_HEADER>(dos).e_magic);

第一个字段等于 3 .我有两个结构,具有相同的字段和完全相同的大小(我已验证),我采用一个数组,将其转换为这些结构,然后得到不同的字段。

如您所见,有一个 3在数组转储中,但它不应该与结构的第一个字段( e_magic )相关联,这是没有意义的,为什么它会与另一个字段一起使用?

我想我在初始化结构时遗漏了一些东西,但是什么?

最佳答案

没有复制相同的定义,您复制了文档中显示的部分。这是(截断的)actual definition :

STRUCT!{struct IMAGE_DOS_HEADER {
e_magic: WORD,
e_cblp: WORD,
// ...
e_res2: [WORD; 10],
e_lfanew: LONG,
}}

值得注意的是,这使用了 STRUCT macro ,它定义了一些特征,但更重要的是将类型标记为 repr(C) :
#[repr(C)] #[derive(Copy)] $(#[$attrs])*
pub struct $name {
$(pub $field: $ftype,)+
}

没有指定 Rust 结构的布局,因此与 C 结构相比,您的结构有一些其他的排序和填充,并且不会工作。

I realised that winapi was too huge and I wanted my binary file to be less than a megabyte, so I declared the IMAGE_DOS_HEADER structure by myself



这是不正确的推理。未使用的库中的代码将从最终的二进制文件中删除。

也可以看看:
  • Why are Rust executables so huge?
  • 关于winapi - 为什么从 winapi 复制到我的代码中的结构定义没有相同的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59636171/

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