#include <stdio.h> #include <stdlib.h> #include <stddef.h> #define container_of(ptr, type, member) ({ / const typeof( ((type *)0)->member ) *__mptr = (ptr); / (type *)( (char *)__mptr - offsetof(type,member) );}) struct test1 { char *pchar ; int idata ; int *pint ; }; int main() { struct test1 ptest1 ; int *p1 = ptest1.pint ; printf("the address of ptest1 is %p/n", &ptest1) ; printf("the address of p1 is %p/n", p1) ; ptest1.pint = 0x55555555 ; printf("offsetof(struct test1, pint)=%d/n", offsetof(struct test1, pint)) ; printf("container_of(p1, struct test1, pint) = %p/n", container_of(p1, struct test1, pint)) ; //1 printf("containerof(ptest1.pint, struct test1, pint)=%p/n", container_of(&ptest1.pint, struct test1, pint)) ; //2 printf("containerof(ptest1.pint, struct test1, pint)=%p/n", container_of(ptest1.pint, struct test1, pint)) ; //3 return 0 ; } container_of的作用在于,给定某结构体中字段的地址,能够获取该结构体的起始地址。比如上面的例子中示例2。 the address of ptest1 is 0xbfe5ce38 the address of p1 is 0xb7faeff4 offsetof(struct test1, pint)=8 container_of(p1, struct test1, pint) = 0xb7faefec //p1的地址往前移8个字节 containerof(&ptest1.pint, struct test1, pint)=0xbfe5ce38 //使用&ptest1.pint作为第一个参数,获得ptest1的地址 containerof(ptest1.pint, struct test1, pint)=0x5555554d //使用ptest1.pint做第一个参数,只是在该地址的基础上前移8个字节 -------&ptest1.pint是字段的地址,ptest1.pint是字段的值,该值是一个地址。
__mptr指向的是一个type结构里typeof(((type *)0)->member)类型member成员的指针,offsetof(type,member)是这个成员在结构中的偏移,单位是字节,所以为了计算type结构的起始地址,__mptr减去它自己的偏移。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
so:#define offset1(type,member) ((unsigned int)&((type *)0)->member)同样是利用指针索引来进行定位的。 指针 精髓于此?、、