本文主要是介绍container_of学习记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
container_of 主要用于解决
已知
- 某个成员的地址: ptr
- 该成员的名称:member;
- 包含该成员的类型:struct container{…, member,…};
得到
- 包含该成员的类型的实例的地址
简释如下:
#include<stdio.h>
#include <stddef.h>/**< build in macro* #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)*/
/**<* 1. 将任意地址强转为包含该成员的类型的指针:(type*)0xFFFFFFFF; (一般写(type*)0)* 2. 用得到的指针访问该成员: ((type*)0xFFFFFFFF)->member, 相当于得到该成员变量;* 3. 用typeof推断该成员变量的类型:typeof( ((type *)0xFFFFFFFF)->member );* 4. 定义该成员变量类型(第3步推断出的类型)的指针变量: __mptr;* ----------------------------------以上4步推断出成员的类型* 5. 该成员的地址赋值给__mptr;* 6. 该成员的地址减去该成员相对于包含该成员的类型的偏移:offsetof(type,member);得到* 包含该成员的类型的实例对象的首地址;* 7. 将该地址转为包含该成员的类型。OVER*/
#define container_of(ptr, type, member) ({ \const typeof( ((type *)0xFFFFFFFF)->member ) *__mptr = (ptr); \(type *)( (char *)__mptr - offsetof(type,member) );})struct test {int ma;int mb;int mc;
};int main()
{struct test t; ///< 实例对象//const typeof(t.mb) *pmb = &(t.mb); ///< 已知成员mb的地址int *pmb = &(t.mb); ///< 已知成员mb的地址struct test *tp = container_of(pmb, struct test, mb); ///< 由该对象的成员地址得到实例对象的地址printf("object addr: %p\n", &t);printf("container_of: %p\n", tp);return 0;
}
这里我们已知:类型test的实例对象t的成员mb的地址pmb,用container_of得到该实例对象t的首地址tp。
这篇关于container_of学习记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!