Проблема заполнения байтов на поперечной дуге - PullRequest
1 голос
/ 06 сентября 2011

Я заметил, что sizzeof () в моей структуре программы отличается на платформах x86 и x64. Это из-за заполнения байтов. Из-за одного требования (когда мое приложение взаимодействует между собой через арку m / c), мне нужно убедиться, что цель должна получить тот же размер структуры, который отправитель отправил через nammedpipe (в моем случае я не могу снова прочитать канал остальные данные ..). Мне нужен способ в C ++, если я могу безопасно отключить / включить заполнение или удалить байты заполнения перед использованием оператора sizeof () в этой структуре.

Спасибо ..

[РЕДАКТИРОВАТЬ | ЗАКЛЮЧЕНИЕ]: просто вход для тех, кто пытается найти решение для подобной проблемы. Попробовал много глупостей, чтобы обойти эту проблему, но одно возможное решение, упомянутое здесь, создало проблему другим способом, отладка которого занимала много времени. Лучший вариант решения этой проблемы, который я мог бы найти, - это использовать методы сериализации и десериализации, как указано в разделе «R ..».

Ответы [ 5 ]

4 голосов
/ 06 сентября 2011

Если вы набираете #pragma pack (1) перед вашей структурой, это должно отключить заполнение.Это работает как на visual studio, так и на gcc.Возможно, вы также захотите использовать #pragma pack (push) и #pragma pack (pop) для сохранения и восстановления предыдущих правил заполнения.Например:

#pragma pack(push)
#pragma pack(1)
struct
{
...
};
#pragma(pop)
4 голосов
/ 06 сентября 2011

Избегайте написания кода, который использует sizeof структуры / объединения.Для переносимости используйте sizeof для отдельных элементов:

const int struct_size = sizeof(x.member1) + sizeof(x.member2) + ...;
2 голосов
/ 06 сентября 2011

Не забудьте также убедиться, что вы используете независимые от арки элементы структуры - если две разные арки имеют, скажем, разный размер int, удаление отступов не поможет.Попробуйте вместо этого использовать типы stdint.h, например.int32_t вместо int.

2 голосов
/ 06 сентября 2011

Какой компилятор вы используете? Вы можете использовать атрибут GCC packed, чтобы сказать компилятору не добавлять какие-либо отступы в вашу структуру. Другие компиляторы, вероятно, имеют аналогичную функцию.

http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

Атрибут aligned также может вам помочь.

1 голос
/ 07 сентября 2011

Другие уже указывали, что в дополнение к заполнению размеры типов могут варьироваться в зависимости от архитектуры.В дополнение к этому, порядок байтов также может варьироваться (не между 32- и 64-битными процессорами Intel, но, если его выбросят другие, это может стать проблемой).

Так что сериализация - хорошая идея.В основном просто создайте функцию для записи и одну для чтения для каждой архитектуры.

Функция записи будет записывать каждый соответствующий байт каждого элемента структуры, причем элементы записываются в известном порядке, а байты каждого элемента также в известном порядке (скажем, наиболее значимым первым).Если размеры типа варьируются между платформами, запишите столько байтов типа, сколько будут поддерживать все платформы.

Функция чтения должна делать обратное тому, что делает функция записи, и обнулять любые байты, которые не включены в сериализованные данные.Функции не сложны в написании, и их использование делает ненужным заполнение, порядковый номер и (часто) размеры основных типов.

...