我在内存中使用以下C结构:
typedef struct MyStructHdr
{
char text[4];
int version_num;
uint64 init_value;
uint64 entries[];
} MyStructHdr;
typedef MyStructHdr *MyStruct;
Field entries[]
是指向某个灵活数组的指针。类型uint64
是定制的便携式应用程序特定类型,在32位OS上增加了uint64_t
支持。
我必须正确地将此结构写入文件,以便以后可以在同一平台/ OS上使用mmap()
:
map = (MyStruct) mmap(NULL, MyStructActualSize,
PROT_READ | PROT_WRITE, MAP_SHARED,
mystruct_fd, 0);
我现在要做什么?我只是简单地使用MyStruct
逐一写入entries[]
字段(并通过缓冲区逐个写入write()
字段)。最后写入CRC32
校验和。
在我使用的所有64位系统上,一切都正常。似乎前4个字符+ 32位int
对齐到单个64位块中,并且uint64
只是扩展为uint64_t
,因此在写入后,所有内容均正确mmap
编写。
但是,我担心在32位系统或某些特定的OS /体系结构上,将应用不同的对齐规则,并且没有uint64_t
,并且uint64
扩展为类似内容:
{
int val1;
unsigned long int val2;
}
写入后我将得到不正确的mmap
。
将这种结构写入文件并在之后使用mmap
的可移植方式是什么?
P.S。实际上,这全都与PostgreSQL扩展有关,uint64
这里是pg_atomic_uint64
,但我认为这个问题更笼统。
您不应该一个个地写成员,因为这不会考虑成员之间的填充。一次写下整个内容:
write(fd, MyStruct, sizeof(MyStructHdr) + entry_count * sizeof(uint64));
其中entry_count
是灵活数组成员中的元素数。