Я просто предлагаю вручную чтение/запись членов структуры в отдельности. Упаковка, использующая ваши директивы компилятора, может привести к проблемам с неэффективностью и переносимостью с несвязанным доступом к данным. И если вам приходится иметь дело с контентом, легко поддерживать это позже, когда ваши операции чтения разбиваются на члены поля, а не на целые структуры.
Другое дело, и это относится скорее к проблемам с футуристическим обслуживанием, заключается в том, что вы не хотите, чтобы ваш код сериализации или файлы, которые люди до сих пор сохраняли, могли сломаться, если вы немного измените структуру (добавьте новые элементы или даже изменить порядок в качестве оптимизации строки кэша, например). Таким образом, вы потенциально столкнетесь с гораздо меньшей болью с кодом, который обеспечивает немного больше передышки, чем сброс содержимого памяти структуры непосредственно в файл, и это часто будет стоить усилий по сериализации ваших членов по отдельности.
Если вы хотите, чтобы обобщить картину и уменьшить количество шаблонных вы пишете, вы можете сделать что-то подобное в качестве основного примера, чтобы начать и построить на:
struct Fields
{
int num;
void* ptrs[max_fields];
int sizes[max_fields];
};
void field_push(struct Fields* fields, void* ptr, int size)
{
assert(fields->num < max_fields);
fields->ptrs[fields->num] = ptr;
fields->sizes[fields->num] = size;
++fields->num;
}
struct Fields s_fields(struct s* inst)
{
struct Fields new_fields;
new_fields.num = 0;
field_push(&new_fields, &inst->i1, sizeof inst->i1);
field_push(&new_fields, &inst->s1, sizeof inst->s1);
field_push(&new_fields, &inst->c1, sizeof inst->c1);
return new_fields;
}
Теперь вы можете использовать эту Fields
структуры с функциями общего назначения для чтения и записи членов любой структуры, например, так:
void write_fields(FILE* file, struct Fields* fields)
{
int j=0;
for (; j < fields->num; ++j)
fwrite(fields->ptrs[j], fields->sizes[j], 1, file);
}
Это, как правило, немного легче работать, чем некоторый функционал for_each_field
такой подход прием обратного вызова.
Теперь все, что вам не придется беспокоиться о том, когда вы создаете какую-то новую-структуру S
, чтобы определить отдельную функцию для вывода struct Fields
из экземпляра, чтобы затем включить все те общие функции, которые Вы написали, что работа с struct Fields
в настоящее время работают с этим новый S
type автоматически.
См. Принятый ответ на http://stackoverflow.com/questions/4306186/structure-padding-and-structure-packing – rslemos
Это специфичный для компилятора файл. Какой компилятор вы используете? –
Вы можете выполнить итерацию по массиву и написать каждый элемент структуры отдельно. – ace