Заставить структуру C++ плотно упаковать
Я пытаюсь прочитать в двоичном файле. Проблема в том, что создателю файла не потребовалось время, чтобы правильно выровнять структуры данных по их естественным границам, и все упаковано плотно. Это затрудняет чтение данных с использованием структур C++.
Есть ли способ заставить struct
быть плотно упакованным?
Пример:
struct {
short a;
int b;
}
Выше структура составляет 8 байтов: 2 для short a
2 для набивки, 4 для int b
, Однако на диске данные составляют всего 6 байтов (не имея 2 байта заполнения для выравнивания)
Обратите внимание, что фактические структуры данных - это тысячи байтов и множество полей, включая пару массивов, поэтому я бы предпочел не читать каждое поле по отдельности.
2 ответа
Если вы используете GCC, вы можете сделать struct __attribute__ ((packed)) { short a; int b; }
На VC++ вы можете сделать #pragma pack(1)
, Эта опция также поддерживается GCC.
#pragma pack(push, 1)
struct { short a; int b; }
#pragma pack(pop)
У других компиляторов могут быть варианты сделать плотную упаковку структуры без заполнения.
Вам нужно использовать специфическую для компилятора нестандартную директиву, чтобы указать 1-байтовую упаковку. Например, под Windows:
#pragma pack (push, 1)
Проблема в том, что создатель файла не потратил время на правильное выравнивание структуры данных, и все упаковано плотно.
На самом деле, дизайнер поступил правильно. По словам Стандарта, можно применять отступы, но в них не говорится, сколько отступов следует применять в каких случаях. Стандарт даже не говорит, сколько битов в байте. Даже если вы предполагаете, что, хотя эти вещи не указаны, они все равно должны быть одинаково разумными на современных машинах, но это просто неправда. Например, на 32-разрядной машине с Windows заполнение может быть одним, а на 64-разрядной версии Windows - другим. Может быть, так и будет - дело не в этом. Дело в том, что вы не знаете, какой будет заполнение в разных системах.
Таким образом, "упаковав все это", разработчик сделал единственное, что мог - использовать некоторую упаковку, в которой он может быть уверен, что каждая система сможет понять. В этом случае эта общепринятая упаковка - не использовать заполнение в структурах, сохраненных на диске или переданных по проводам.