Я использую следующую C структуру в памяти:
typedef struct MyStructHdr
{
char text[4];
int version_num;
uint64 init_value;
uint64 entries[];
} MyStructHdr;
typedef MyStructHdr *MyStruct;
Поле entries[]
- указатель на некоторый гибкий массив. Тип uint64
- это пользовательское переносимое приложение, специфицирующее тип c, которое добавляет поддержку uint64_t
в 32-битной ОС.
Мне нужно правильно записать эту структуру в файл, чтобы я мог использовать 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-битной системе или какой-либо другой c ОС / архитектуре, где применяются разные правила выравнивания и нет uint64_t
и uint64
расширяется в нечто вроде:
{
int val1;
unsigned long int val2;
}
Я получу неправильный mmap
'после записи.
Что такое переносимый способ записи такой структуры в файл и использования mmap
после этого?
PS На самом деле, это все о PostgreSQL расширении и uint64
здесь pg_atomic_uint64
, но я думаю, что этот вопрос является более общим.