Я удаляю свой исходный ответ из-за неполноты понимания вашей проблемы.Теперь я понял это после прочтения следующей статьи: Написание независимого от порядкового номера кода в C
Сначала проблема с выравниванием:
Как упомянуто500 - Внутренняя ошибка сервера
У вас будут проблемы с копированием данных, поскольку ваша структура будет содержать отступы.В вашем примере к структуре будет добавлен 1 байт.
Ниже приведен пример макета памяти, полученного из VS при реализации 32-битного языка C.
size = 8
Address of test0 = 5504200
Padding added here at address 5504201
Address of test1 = 5504202
Address of test2 = 5504204
Чтобы указать правила выравнивания,компилятор должен использовать, используйте директиву препроцессора pack .
// Aligns on byte boundaries, then restore alignment value to system defaults
#pragma pack ( 1 )
#pragma pack ()
// Aligns on byte boundaries, restores previously assigned alignment value.
#pragma pack ( push, 1 )
#pragma pack (pop)
Используя ваш пример, определение структуры будет выглядеть примерно так:
#pragma pack ( 1 )
typedef struct {
unsigned char test0;
unsigned short test1;
unsigned int test2;
} Foo_t;
#pragma pack ()
Foo_t s2;
printf("\nsize = %d\n", sizeof(Foo_t));
printf(" Address of test0 = %u\n", &s2.test0);
printf(" Address of test1 = %u\n", &s2.test1);
printf(" Address of test2 = %u\n", &s2.test2);
Результат:
size = 7
Address of test0 = 10287904
Address of test1 = 10287905
Address of test2 = 10287907
Вторая проблема с порядком байтов:
Проблема заключается в том, как целые числа хранятся в памяти на 32-разрядных компьютерах с архитектурой x86.На машинах x86 они хранятся в порядке с прямым порядком байтов.
Например, при копировании 2-байтового массива, содержащего байты x34 и x56, в короткое целое число будет храниться как x56 (младший байт) x34 (следующий байт)).Это не то, что вы хотели.
Чтобы решить эту проблему, вам нужно переключить байты, как предлагали другие.Я хочу создать функцию, которая будет выполнять замену байтов на месте.
Пример:
int main()
{
#pragma pack ( 1 )
typedef struct {
unsigned char test0;
unsigned short test1;
unsigned int test2;
} Foo_t;
#pragma pack ()
unsigned char tempBuf[7] = { 0x12, 0x34, 0x56, 0x78, 0x0A, 0x06, 0x77 };
Foo_t foo;
memcpy(&foo, &tempBuf[0], 7);
//foo.test0 = netToHost (&foo,0,1); // not needed
foo.test1 = reverseByteOrder(&foo, 1, 2);
foo.test2 = reverseByteOrder(&foo, 3, 4);
printf("\n After memcpy We have %02X %04X %08X\n", foo.test0, foo.test1, foo.test2);
}
int reverseByteOrder(char array[], int startIndex, int size)
{
int intNumber =0;
for (int i = 0; i < size; i++)
intNumber = (intNumber << 8) | array[startIndex + i];
return intNumber;
}
Вывод:
After memcpy We have 12 3456 780A0677