Linux内核 container_of 宏和 offsetof 宏分析
来源:互联网 发布:网络作家排名 编辑:程序博客网 时间:2024/05/16 19:24
1、#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER )
宏功能:获得一个结构体变量成员在此结构体中的偏移量。
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址,即相对于0的偏移量,要的就这个;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型,size_t应该最终为unsigned int类型。
此宏的巧妙之处在于将 0 转换成(TYPE*),这样结构体中成员的地址即为在此结构体中的偏移量。
示例:
#include <stdio.h>
#define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER))
struct _test_
{
int x;
int y;
float z;
};
int main(void)
{
int temp = -1;
temp = offsetof(struct _test_, z);
printf("temp = %d\n", temp);
return 0;
}
运行后结构为:temp = 8。
显然求出了 结构体成员变量 z 在结构体中的偏移量为 8。
2、#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
宏功能:从结构体(type)某成员变量(member)指针(ptr)来求出该结构体(type)的首指针。
这里比较啰嗦,举个例子吧,然后分析:
#include <stdio.h>
#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) );})
struct _test_
{
int x;
int y;
int z;
};
void Assignment(struct _test_ *t)
{
t->x = 1;
t->y = 2;
t->z = 3;
}
void GetheadPoint(int *tz)
{
struct _test_ *p;
int temp = -1;
p = container_of(tz,struct _test_, z); //根据成员变量的地址获得该结构体的首地址
temp = p->y; //根据首地址获得其中另外一个成员变量的值
printf("line31 = %d\n", temp);
}
int main(void)
{
int temp = -1;
struct _test_ tmp; //定义一个结构体变量
Assignment(&tmp); //给这个变量赋值
GetheadPoint(&tmp.z); //只传给这个函数一个结构体成员变量的地址
printf("line43 tmp - >x = %d\n", tmp.x);
return 0;
}
运行结果为:
line31 = 2
line43 tmp - >x = 1
大概解释一下:先定义一个结构体并给其赋值,现在 GetheadPoint函数只传入这个结构体的一个子成员变量地址。在 GetheadPoint函数中通过container_of宏来获得此结构体的首指针,通过此首指针即可以获得此结构体的其它子成员的值。
1、.typeof( ( (type *)0)->member )为取出member成员的变量类型。
2、定义__mptr指针ptr为指向该成员变量的指针
3、mptr为member数据类型的常量指针,其指向ptr所指向的变量处
4、.(char *)__mptr转换为字节型指针。(char *)__mptr - offsetof(type,member))用来求出结构体起始地址(为char *型指针),然后(type *)( (char *)__mptr -offsetof(type,member) )在(type *)作用下进行将字节型的结构体起始指针转换为type *型的结构体起始指针。
5、.({ })这个扩展返回程序块中最后一个表达式的值。
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- Linux内核 container_of 宏和 offsetof 宏分析
- linux 内核中container_of和offsetof宏定义解析
- 对linux内核的container_of和offsetof宏的理解
- offsetof和container_of两个内核中的宏
- 内核:offsetof + container_of 分析
- container_of 宏、offsetof 宏 分析
- Linux 内核中宏 offsetof 与 container_of 的含义
- offsetof宏和container_of宏
- container_of 和 offsetof 宏详解
- Linux内核实现List二个关键的宏offsetof 和 container_of
- 关于Linux/kernel.h中的offsetof和container_of宏
- Linux内核:container_of宏分析
- offsetof与container_of宏
- offsetof与container_of宏
- 禁止在 .NET Framework 中执行用户代码。启用 "clr enabled" 配置选项 解决办法
- SATA接口硬加密器
- 通过ANR来查看死锁
- Master Note: Troubleshooting Oracle Temporary Tablespaces (Doc ID 1524594.1)
- 娶一房媳妇,憧憬着未来的旖旎
- Linux内核 container_of 宏和 offsetof 宏分析
- hthtrytru
- Flex 正则表达式整理
- Struts2的上传附件
- 深度优先搜索遍历(DFS)——邻接表存储
- Struts2+Spring+Hibernate step by step 03 整合Spring之一(在DAO层验证用户名和密码)
- 优化MySQL,还是使用缓存?
- 将OPenCV的Dll 动态连接库改名字,变成自己想要的动态连接库名字
- Ubuntu 9.04下arm-linux-gcc交叉编译环境的搭建