Introduction
I have a 4-byte data, which is defined as:
Bits 31-24 | Bits 21-23 | Bit 20 | Bit 19-10 | Bit 9-0 |
Pixel Data | Spare set to 0 | Direction | Pixel Y address (row) | Pixel X address (col) |
When using MS compiler on intel PC, its rule is: bit fields are laid out from the least significant bit to the most significant bit. So in my VC++ code, I define the structure as:
#pragma pack(1)
typedef struct
{
unsigned int pixel_y_address : 10;
unsigned int pixel_x_address : 10;
unsigned int direction : 1;
unsigned int unused : 3;
unsigned int pixel_data : 8;
} Image_Segment_Data;
Now I need to transfer these data to my program running on PowerPC. The operating system here is VxWorks. I found out that the rule here is reversed comparing with MS compiler: bit fields are laid out from the most significant bit to the least significant bit. So in my VxWorks code, I define the structure as:
struct image_segment_data_
{
unsigned int pixel_data : 8;
unsigned int unused : 3;
unsigned int direction : 1;
unsigned int pixel_x_address : 10;
unsigned int pixel_y_address : 10;
} __attribute__ ((packed));
typedef image_segment_data_ Image_Segment_Data;
But the story does not stop here. When sending out data using TCP/IP socket, the MSB in PC code is received as LSB in VxWorks code. That is, data from PC {pppp,pppp,uuud,xxxx,xxxx,xxyy,yyyy,yyyy} is parsed by VxWorks as {yyyy,yyyy,xxxx,xxyy,uuud,xxxx,pppp,pppp}. What a hell! This is because the host byte order is not the same on these two platforms. So the data must be converted before sent by PC. To facilitate this, a union is defined as:
typedef union
{
Image_Segment_Data data;
unsigned long raw;
} Image_Segment_Union;
The reversing is easy:
Image_Segment_Data originData;
Image_Segment_Union originUnion;
Image_Segment_Union tempUnion;
when sending from PC:
originUnion.data = originData;
tempUnion.raw = htonl(originUnion.raw) ;
send(sd, (char *)&tempUnion.raw, sizeof(tempUnion.raw), 0);
when receiving from PowerPC:
recv(sd, (char *)&tempUnion.raw, sizeof(tempUnion.raw));
originUnion.raw = ntohl(tempUnion.raw);
originData = originaUnion.data
Conclusion
That’s all I figured out. Thank you, Time Finer and axiac, for pointing out my mistake on understanding this issue.
Reference: Joaquín M López Muñoz’s answer to my question "Help! About structure alignment". (No wonder I love CP so much!)