1. 话题引出在技术交流群中,一位小哥分享了一个关于共联体类型强制转化的讨论。这引发了笔者的兴趣,因为这种操作在通信协议的拆包、解包过程中非常常见。尽管笔者在参加工作后才在部门代码中接触到这类操作,但...
在技术交流群中,一位小哥分享了一个关于共联体类型强制转化的讨论。这引发了笔者的兴趣,因为这种操作在通信协议的拆包、解包过程中非常常见。尽管笔者在参加工作后才在部门代码中接触到这类操作,但这次决定整理并分享给各位,以便大家更好地理解和应用。
在通信数据接收或发送末端,帧头、长度和数据部分通常位于字节流中。例如,在UART通信中,这些数据最终都会被放置在SendBuff[N]或RecBuff[N]中,然后发送出去。
如果你需要将结构体打包并逐个填充byte到发送或接收buff中,这个过程可能会比较繁琐。然而,通过结构体指针强制类型转换为uint8_t *pSendBuff,然后进行字节流发送,可以使过程变得更加简洁。
在这个过程中,还需要注意字节序、对齐等问题。以下是一个模拟此过程的代码示例:
#include
#include
#pragma pack(1)
typedef struct tagPack { int Head; int Len; char Data[2];
} sPack;
#pragma pack()
int main(int argc, char argv[]) { sPack stSendPack; sPack *pstRevPack = NULL; uint8_t *SendBuff = NULL; uint8_t RevBuff[20] = {0}; int cnt = 0; // 假设这里进行了数据填充和发送操作 // ... // 将结构体转换为字节流 SendBuff = (uint8_t *)&stSendPack; for (cnt = 0; cnt < sizeof(stSendPack); cnt++) { RevBuff[cnt] = SendBuff[cnt]; } // 将字节流转换回结构体 pstRevPack = (sPack *)RevBuff; // 进行后续处理 // ... return 0;
} 在处理网络通信时,字节序(也称为网络字节序)是一个需要特别注意的问题。C语言标准库提供了htonl、htons、ntohl和ntohs等函数来处理字节序转换。
以下是一个使用htonl函数进行网络字节序转换的示例:
#include
#include
int main() { uint32_t local = 0x12345678; uint32_t net = htonl(local); printf("Local byte order: 0x%08X\n", local); printf("Network byte order: 0x%08X\n", net); return 0;
} 在C语言中,结构体成员可能会因为对齐要求而增加填充字节。这可能导致结构体大小不是成员大小之和。为了解决这个问题,可以使用#pragma pack指令来控制结构体的对齐方式。
在上面的代码示例中,#pragma pack(1)指令确保了结构体成员没有额外的填充字节。
通过本文,我们了解了C语言共联体的秘密,以及如何利用共联体进行高效编程。掌握这些技巧可以帮助我们在通信协议解析等场景中更加得心应手。在实际应用中,请根据具体需求调整代码,并注意字节序和对齐问题。