在Linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member)。已知结构体type的成员member的地址ptr,求结结构体type的起始地址。
container_of在已知一个结构体的成员的名字,以及其地址的情况向,反推该结构体的首地址
offsetof获取一个结构体成员在结构里面的偏移,结构体首地址 = 成员地址- 成员偏移
以下是一个container of函数例子:
#includelinux 内核宏container_of(ptr, type, member)#include #define offsetof(TYPE,MEMBER) ((int) &((TYPE *)0)->MEMBER) //为什么这样就能得到偏移 #define container_of(ptr, type , member) ({ const typeof(((type *)0)->member) *__mptr = (ptr) ; (type *)((char *)__mptr - offsetof(type,member)) ;}) #pragma pack(4) struct ptr { char a ; short b ; int c ; double d ; }; #pragma pack() int main(void) { struct ptr Pt ; struct ptr *pt ; printf("ptr:%dn",sizeof(struct ptr));//16 //获取结构体的首地址 printf("ptr:%pn",&Pt); //0028FEA8 Pt.a = 'a'; Pt.b = 2 ; Pt.c = 4 ; Pt.d = 12.04 ; //通过container of获取结构体的首地址 pt = container_of(&Pt.c, struct ptr , c); printf("pt:%pn",pt); //0028FEA8 printf("a:%cn",pt->a) ; //'a' printf("b:%dn",pt->b) ; //2 printf("c:%dn",pt->c) ; //4 printf("d:%.2lfn",pt->d);//12.04 return 0 ; }
通过计算member的地址,获取 ptr 所在的结构体type的首地址。
#define container_of(ptr, type, member) ({ const typeof(((type *)0)->member) *__mptr = (ptr); (type *)((char *)__mptr - offsetof(type,member));}) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)typeof 获取成员类型
const typeof( ((type *)0)->member ) *__mptr = (ptr);
将ptr 赋值给 __mptr,如果ptr的类型和member指针的类型不一致,这个赋值会有警告,这个是代码严谨性的体现。
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
成员member 在结构体TYPE中的相对地址
ptr - offset
获取ptr所在的结构体的地址。
嵌入式Linux与物联网软件开发:C语言内核深度解析 ISBN:9787115432940
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)