I remove my original answer due to not fulling understand your problem. I get it now after reading the follow article on: Writing endian-independent code in C
First the alignment issue:
As mention by 500 - Internal Server Error
You will have issues coping the data because your structure will contain padding. In your example, 1 byte will be added to the structure.
Here is a memory layout example obtain from VS on a 32 bit C implementation.
size = 8
Address of test0 = 5504200
Padding added here at address 5504201
Address of test1 = 5504202
Address of test2 = 5504204
To specify the alignment rules the compiler should use, use the preprocessor directive 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)
Using your example, the structure definition will look something like this:
#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);
Result:
size = 7
Address of test0 = 10287904
Address of test1 = 10287905
Address of test2 = 10287907
Second the endian issue:
The issue here is how integers are being stored in memory on a 32-bit x86 machines. On x86 machines they are store in little endian order.
For an example, copying a 2 byte array containing the bytes x34 & x56 into an short integer will be stored as x56 (low order byte) x34 (next byte). Which is not what you wanted.
To fix this problem you need to switch the bytes around as other suggested. My take on this is to create a function that would do the byte swap in place.
Example:
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;
}
The output is:
After memcpy We have 12 3456 780A0677
memcpy: endianness is one, as you suspect you'll have to swap the byte order for multi-byte values on Windows. The other problem is alignment/padding: by default, your struct above will have padding bytes to align each field on a natural boundary (an offset divisible by its size).