结构打包和对齐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的代码显示两个typedef
s,对吧?【参考方案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的主要内容,如果未能解决你的问题,请参考以下文章