Der Präprozessor ist nicht in der Lage, Strukturoffsets zu berechnen, so dass keine Menge an Makrozauber allein Ihre Offsets für Sie abgibt.
Wenn Sie für eingebettete Ziele erstellen, können Sie wahrscheinlich .bin-Dateien erstellen (nicht elf, coff, mach-o). Wenn Sie jeden Ihrer Zielcompiler verwenden, um ein Array von Offsets in einer Objektdatei zu erstellen und dann in eine Bin-Datei zu speichern, sollte es möglich sein, die Bin-Dateien für jedes Ihrer Ziele zu vergleichen. Es wäre eine gute Idee, den Prozess für Build-Time-Checks zu automatisieren. Hier
ist ein Beispiel dafür, was ich spreche:
#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)
};
Dies ist nur eine Tabelle von Offsets erzeugt. Erstellen Sie dies für eine Mipsel und x86_64 und vergleichen. Hier ist eine Make-Datei:
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 $< > [email protected]
hexdump.$(T2).txt: offsets.$(T2).bin
hexdump -C $< > [email protected]
offsets.$(T1).bin: offsets.$(T1).o
$(OBJCPY1) -j.data -O binary $< [email protected]
offsets.$(T2).bin: offsets.$(T2).o
$(OBJCPY2) -j .data -O binary $< [email protected]
offsets.$(T1).o: offsets.c
$(CC1) -Wall -c -o [email protected] $<
offsets.$(T2).o: offsets.c
$(CC2) -Wall -c -o [email protected] $<
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
nun die Offsets zu vergleichen ist recht einfach:
[email protected] ~/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
[email protected] ~/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
Die Mips sendet einen 32-Byte-Datenabschnitt anstelle der x86 20 Byte. Wenn Sie die Größe offsets
festlegen, sollten Sie cmp
verwenden können, um die beiden in Ihrem Build zu vergleichen.
Wenn Ihre Ziele eine unterschiedliche Endgültigkeit aufweisen, müssen Sie möglicherweise das Makro o
so ändern, dass ntohl
oder ähnliches verwendet wird, um beide Compiler zum Ausgeben von Ganzzahlen im selben Format zu veranlassen.
Es gibt ein Makro 'offsetof()' in 'stddef.h'. Siehe https://en.wikipedia.org/wiki/Offsetof – cdarke
Die DWARF-Informationen in jedem Objekt haben das (wenn Debug-Informationen aktiviert sind). Aber es bedarf einiger Analyse, um die Daten zu extrahieren. – kaylum
Sie können sicher die 'pack' Breite für Ihre Struktur festlegen und den gleichen Wert für beide Projekte erzwingen. – LPs