通信用到的结构体定义:对齐方式,成员偏移量计算,结构体成员为指针变量处理;
1.__packed 或 __attribute__((packed))
这两个关关键子是编译系统的关键字,用到给出于这两个关键字声明的类型或变量的对齐方式为字节对齐,对结构体来说,不会按成员的类型进行对齐,可以节约内存空间,但CPU在访问速度会降低;
在自定义的通信结构体中可以按字节进行数据的打包与拆包;不用考虑自然对齐时会自动插入空字节;
2.offsetof 和 container_of
2.1.offsetof
/** * @brief offsetof:获取结构体中成员变量member相对于结构体的地址偏移量 * @param type:结构体类型 * @param member:结构体type的成员member名 */ #define offsetof(type, member) ((size_t) &((type *)0)->member)
原理说明:
(type *)0:将内存地址0设置为type类型指针的起始地址;
((type *)0)->member:取type类型指针变量的成员member,不能独立使用会报错;
&((type *)0)->member:取type类型指针变量的成员member的地址,因为起始地址为0,所以&((type *)0)->member取到的就是member成员相对与结构体变量的首地址偏移量;
2.2.container_of
/** * @brief container_of:知道结构体中某个元素的指针(ptr),反推这个结构体变量(ptr所在的变量)的指针(首地址),继而得到结构体中的其他元素。 * @param ptr:指向结构体成员member的指针 * @param type:结构体类型 * @param member:结构体type的成员member名 * @retval ptr所在结构体变量的整个结构体(类型type)变量的指针,类型是(type *) */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
原理说明:
typeof:获取变量的数据类型;
typeof( ((type *)0)->member ) :获取type结构体成员member的数据类型;
const typeof( ((type *)0)->member ) *__mptr :定义一个 const typeof( ((type *)0)->member ) 类型的指针,用于接收ptr的指针,防止对ptr指针进行误操作;
( (char *)__mptr - offsetof(type,member) ):用ptr的指针减去member成员在结构体中的偏移量得到ptr所在结构体变量的首地址;
(type *)( (char *)__mptr - offsetof(type,member) ) :将地址强制转换为结构体type类型;
3.结构体成员为指针变量处理
通信结构体中成员变量为指针类型,当要发通信数据时要注意不要把指针作为有效数据给发送了,而应该将指针指向的有效数据代换原来的指针的位置进行发送;
浙公网安备 33010602011771号