结构打包和对齐mingw

Posted

技术标签:

【中文标题】结构打包和对齐mingw【英文标题】:Struct packing and alignment with mingw 【发布时间】:2014-07-23 19:54:13 【问题描述】:

我在 PC(mingw32、32 位架构)上模拟来自嵌入式系统(stm32、Keil µVision 5、MDK-ARM)的代码。 ARM 编译器的对齐方式与我的桌面 mingw build 不匹配:

// ARM Code (ARM compiler uses __packed)
typedef __packed struct _file

    uint8_t var1;
    uint16_t var2;
 FILE;

// PC mingw gcc code trying to emulate layout above.
typedef struct __attribute__((packed, aligned(1))) _file

    uint8_t var1;
    uint16_t var2;
 FILE;

在源代码中,我执行以下操作:file.var1 = 0x22; file.var2 = 0xAA55; 然后将其写入内存。当我在嵌入式系统上读取内存时,它显示0x22, 0x55, 0xAA。在 Windows 机器上,它读取 0x22, 0xFF, 0x55, 0xAA,在第 2nd 字节处有填充。我该如何纠正这种行为?

【问题讨论】:

OT:我建议使用与 FILE 不同的名称,该名称由标准库定义,并且您在 Windows 环境中包含的任何标准头文件也可能包含 stdio.h ,即使嵌入式环境没有它 哈哈是的,你是对的,但这不是我实际使用的代码。为了演示这种行为,我更改了名称并将其删减。 你误解了,误用语言是问题所在。实现定义的功能就是这样。没有理由期望他们在某一天/版本之外以这种方式工作...... 【参考方案1】:

根据the GCC manual's examples,attribute 应该在结构的字段之后,即:

// PC Code
typedef struct

    uint8_t var1;
    uint16_t var2;
 __attribute__((packed, aligned(1))) FILE;

我还删除了无意义的结构标记 (_file)。

当我快速测试时,上面的sizeof 值为3

【讨论】:

warning: 'packed' attribute ignored [-Wattributes] FILE __attribute__((packed, aligned(1))); 嗯嗯.. @artlessnoise 什么不是typedef? OP的代码显示两个typedefs,对吧?【参考方案2】:

我自己修复了它 -> 使用 -mno-ms-bitfields 编译有帮助!上面的代码确实是正确的。有必要告诉 mingw 使用 gcc 的位域组织而不是 microsoft 样式。尽管那时代码可能无法用 microsoft 编译器编译,但我现在不在乎。

【讨论】:

好吗?代码中没有位域,但可能编译器正在为某些位域做准备。 我猜是mingw实现的问题。 这个old gcc post 解释了它在做什么。问题不是很清楚。听起来您正在将 PC 代码移植到 ARM;不是相反。通常,cygwin 想要兼容Windows 的方式。即,您的代码应使用 DLL 等执行 Windows 操作,而不是尝试模拟 ARM。我想我会研究 XEN 等来实际模拟这个慢速 ARM CPU。 也就是说,gcc_struct 可能是更好的选择。请参阅 6.36.5 i386 变量属性部分。如果你调用实际的 Windows 代码,你可能需要另一个。 我在 GCC 文档的任何地方都找不到关于 -mno-ms-bitfields 的文档。有没有指向那个的 URL 链接?【参考方案3】:

打包的属性是broken on mingw32 compilers。另一种选择是使用 pragma pack:

#pragma pack(1)
typedef struct _file

  uint8_t var1;
  uint16_t var2;
 FILE;

【讨论】:

以上是关于结构打包和对齐mingw的主要内容,如果未能解决你的问题,请参考以下文章

C++ 类打包/成员对齐

C++结构对齐问题

qt5.8 mingw 打包的exe要怎么在xp上运行

“现在打包强制记录的字节对齐”是啥意思?

C++ 结构体对齐

win8 下qt5.8 mingw 打包的exe要怎么在xp上运行