内核版本:linux-2.6.37.1
container_of的宏定义如下:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
使用container_of宏后,可通过父结构体type中的成员member的已知地址ptr,来寻找
当前ptr地址所属的父结构体type的地址。
例子:
struct test{
int a,
char b,
struct tmp,
}
struct tmp *pt
pt = &p.tmp (p是从其他途径获得的结构体,现在需要计算这个p的地址)
struct teset *t = container_of(pt, struct test, tmp)
使用container_of宏后可以通过已知的struct tmp地址pt来计算得到p的地址。下面结合
根据例子分析container_of宏代码
const typeof( ((type *)0)->member ) *__mptr = (ptr);
将mptr指针将之转换成member类型的指针。这是通过首先将0地址强制转换成type类型的
地址(即struct test地址)
struct test{ 0x00000000
int a, 0x00000000
char b, 0x00000004
struct tmp, 0x00000005
}
然后通过typeof(X->member)来获得type类型中member的类型,
再将mptr强制转换为member类型,最后对mptr赋已知的地址ptr。
这样最后只要通过ptr指针减去一个偏移量即可获得父结构体重type
的地址。
(type *)( (char *)__mptr - offsetof(type,member) );})
结合例子总结:例如已知p.tmp的地址pt为0x30005646,通过offsetof(type,member)可以算的
tmp在test中的偏移量为5,则计算可得父结构体p的地址为子结构体tmp的地址0x300005646减
去tmp在父结构体中的偏移量5,即0x30005646-5 = 0x30005641