查看在构建期间如何打包C结构

rit*_*h87 6 c embedded struct packing

有没有办法看看在构建期间如何打包C结构?我已经阅读了几篇关于如何打包结构的类似帖子:

但我想知道是否有某种构建时生成的文件,它向我展示了如何打包结构?我尝试检查链接器生成的映射文件,但它没有此信息.

PS:我试图让一些微控制器通过UART相互通信,因为一个是16位而其他的是32位,每次更新这些结构时我都会遇到一些错误.

eva*_*itl 2

预处理器无法计算出结构偏移量,因此单独使用任何宏魔法都无法为您转储偏移量。

如果您正在构建嵌入式目标,您可能能够创建 .bin 文件(不是 elf、coff、mach-o)。如果您使用每个目标编译器在目标文件中创建偏移量数组,然后将其转储到 bin 文件,则应该可以比较每个目标的 bin 文件。自动化构建时间检查的过程将是一个好主意。

这是我正在谈论的一个例子:

#include <stdint.h>
#include <stddef.h>
typedef struct s1{
    uint16_t f1;
    uint32_t f2;
    uint64_t f3;
    int8_t f4[5];
    uint32_t f5[2];
}s1;

#define o(f) ((int32_t)offsetof(s1,f))

int32_t offsets[]={
    o(f1),
    o(f2),
    o(f3),
    o(f4),
    o(f5)
};
Run Code Online (Sandbox Code Playgroud)

这只是创建一个偏移表。为 mipsel 和 x86_64 构建它并进行比较。这是一个制作文件:

T1:=x86_64-linux-gnu
CC1:=$(T1)-gcc
OBJCPY1:=$(T1)-objcopy
T2:=mipsel-linux
CC2:=$(T2)-gcc
OBJCPY2:=$(T2)-objcopy


.PHONY: all cmp clean hexdumps

all: hexdumps 

hexdumps: hexdump.$(T1).txt hexdump.$(T2).txt

hexdump.$(T1).txt: offsets.$(T1).bin
    hexdump -C $< > $@

hexdump.$(T2).txt: offsets.$(T2).bin
    hexdump -C $< > $@

offsets.$(T1).bin: offsets.$(T1).o
    $(OBJCPY1) -j.data  -O binary $< $@

offsets.$(T2).bin: offsets.$(T2).o
    $(OBJCPY2) -j .data -O binary $< $@

offsets.$(T1).o: offsets.c
    $(CC1) -Wall -c -o $@ $<

offsets.$(T2).o: offsets.c
    $(CC2) -Wall -c -o $@ $<

clean:
    -rm -f offsets.$(T1).o offsets.$(T2).o
    -rm -f offsets.$(T1).bin offsets.$(T2).bin
    -rm -f hexdump.$(T1).txt hexdump.$(T2).txt
Run Code Online (Sandbox Code Playgroud)

现在,比较偏移量非常简单:

evaitl@evbb ~/se $ cat hexdump.mipsel-linux.txt 
00000000  00 00 00 00 04 00 00 00  08 00 00 00 10 00 00 00  |................|
00000010  18 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020
evaitl@evbb ~/se $ cat hexdump.x86_64-linux-gnu.txt 
00000000  00 00 00 00 04 00 00 00  08 00 00 00 10 00 00 00  |................|
00000010  18 00 00 00                                       |....|
00000014
Run Code Online (Sandbox Code Playgroud)

mips 发出 32 字节数据部分,而不是 x86 20 字节。如果您设置了 的大小offsets,您应该能够cmp在构建中使用它来比较两者。

如果您的目标具有不同的字节序,您可能需要更改o要使用的宏ntohl或某些类似的宏,以使两个编译器以相同的格式发出整数。