一个宏定义函数
这时Linux内核里面的一个宏定义,container_of看不懂,真心求教!!
C/C++ code#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
------解决方案--------------------
就是一个宏定义;
当函数里面出现container_of(ptr, type, member)时,直接用后面的替换;
(ptr, type, member)里面都是参数,对应后面的式子;
也可以理解container_of(ptr, type, member)为一个函数;带参数;
1. const typeof( ((type *)0)->member ) *__mptr = (ptr);
是定义一个__mptr指针变量,类型和member的类型一样
typeof是获得一个变量的类型,((type *)0)->member 则是tpye类型中的member 变量,一般type为结构体类型,member 则为其中的变量
这里的0只是作为一个临时的指针地址用,任何可以表示地址的数字都可以代替0
#define container_of(ptr, type, member) ({ /
const typeof( ((type *)0)->member ) *__mptr = (ptr); /
(type *)( (char *)__mptr - offsetof(type,member) );})
1.(type*)0->member为设计一个type类型的结构体,起始地址为0,编译器将结构体的起始的地址加上此结构体成员变量的偏移得到此结构体成员变量的地址,由于结构体起始地址为0,所以此结构体成员变量的偏移地址就等于其成员变量在结构体内距离结构体开始部分的偏移量。即:&(type*)0->member就是取出其成员变量的偏移地址。而其等于其在结构体内的偏移量:即为:(size_t)(& ((type*)0)->member)经过size_t的强制类型转换后,其数值为结构体内的偏移量。该偏移量这里由offsetof()求出。
2.typeof( ( (type *)0)->member )为取出member成员的变量类型。用其定义__mptr指针;ptr为指向该成员变量的指针。__mptr为member数据类型的常量指针,其指向ptr所指向的变量处。
3.(char*)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
这就是从结构体某成员变量指针来求出该结构体的首指针。指针类型从结构体某成员变量类型转换为该结构体类型。
------解决方案--------------------
container_of(ptr, type, member) 就是 已知 member的地址 求 type的地址的一个宏
C/C++ codestruct A
{
int a;
int b;
}
size_t o = offsetof(A, b);
A *p = (A*)malloc(A);
int *pB = p->b;
那么 ((char*)pB-(char*)p) == o
所以 p == (A*)((char*)pB - o), (A*)((char*)pB - o) == p。
container_of(pB, A, b)
展开后为
const typeof( ((A*)0)->b )* __mptr = pB;
(A*)((char*)__mptr - offsetof(A, b))
因为 __mptr = pB, offsetof(A, b) = o
所以 上面的式子可化简为
(A*)((char*)pB - o) => p
------解决方案--------------------
[url请看这里:Linux内核入门(三)—— C语言基本功 =http://blog.csdn.net/olillian/article/details/7264997][/url]
------解决方案--------------------
假设我们有一个结构体C/C++ codetypedef struct
{
int a;
float b;
}Test_Struct;
------解决方案--------------------探讨
container_of(ptr, type, member) 就是 已知 member的地址 求 type的地址的一个宏
C/C++ code
struct A
{
int a;
int b;
}
size_t o = offsetof(A, b);
A *p = (A*)malloc(A);
int *pB = p->b;
那么 ((char*)pB-(cha……