linux中offsetof与container_of宏定义
linux内核中offsetof与container_of的宏定义
#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) );})
offsetof含义:获取结构体中某个成员变量相对于结构体首地址的内存位置偏移;
container_of含义:根据结构体中某个成员变量的内存地址获取结构体的内存首地址。
offsetof宏详解:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
1)、参数TYPE为结构体的类型定义,MEMBER为结构体成员变量名称;
2)、实现方法比较取巧:将0强制转化TYPE类型的指针,然后对MEMBER变量取址;
3)、代码示例:
typedef struct
{
int a;
char b;
void *c;
} off_struct_s;
printf("offset a:%d b:%d c:%d\n", offsetof(off_strcut_s, a), offsetof(off_strcut_s, b), offsetof(off_strcut_s, c));
最终结果为:offset a:0 b:4 c:8
container_of宏详解:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
1)、参数ptr为结构体成员的内存地址,type为结构体类型定义,member为结构体成员变量名称;
2)、typeof为gun编译器系列的内置函数,函数返回当前变量的类型;
3)、const typeof( ((type *)0)->member ) *__mptr = (ptr); 这行定义了一个member类型的指针变量__mptr,并且值初始化为ptr(注意:这里type也是0强制转换);
4)、(type *)( (char *)__mptr - offsetof(type,member) );
这行则是将结构体成员变量的内存地址减去此成员变量与结构体首地址的偏移(offsetof前面已讲解),即为结构体的内存首地址;
5)、代码示例:
off_struct_s stru;
void *ptr;
ptr = (void *)(container_of(&stru.c, off_struct_s, c));
printf("stru_addr:%p container_addr:%p\n", &stru, ptr);
运行结果必然是&stru与ptr的内存地址是一样的,这个例子只是做一个证明,实际使用时肯定是先不知道结构体首地址的,需要由结构体变量地址计算结构体首地址。
其实总结起来很简单,要想根据一个结构体变量的指针计算出结构体本身的指针,只需要当前变量指针减去变量到结构体首的偏移(base = ptr - offset)。
linux中offsetof与container_of宏定义的更多相关文章
- Linux Kernel代码艺术——系统调用宏定义
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...
- C中的预编译宏定义
可以用宏判断是否为ARC环境 #if _has_feature(objc_arc) #else //MRC #endif C中的预编译宏定义 -- 作者: infobillows 来源:网络 在将一 ...
- iOS --- 总结Objective-C中经常使用的宏定义(持续更新中)
将iOS开发中经常使用的宏定义整理例如以下,仅包括Objective-C. 而对于Swift,不能使用宏,则能够定义全局函数或者extension.请參考博客iOS - 总结Swift中经常使用的全局 ...
- container_of宏定义分析---linux内核
问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...
- (转)offsetof与container_of宏[总结]
1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...
- offsetof与container_of宏[总结]
1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...
- offsetof与container_of宏分析
offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...
- VC中预处理指令与宏定义详解
刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...
- 对offsetof、 container_of宏和结构体的理解
offsetof 宏 #include<stdio.h> #define offsetoff(type, member) ((int)&((type*)0)->me ...
随机推荐
- C# 利用socekt做到http监听,怎么样才能做到高性能
c#原始提供了http的监听的类HttpListener,实现了简单的http.文章地址<C# 控制台或者winform程序开启http的监听状态> 但是经过我测试,这个HttpListe ...
- Hexo主题实现多级分类显示
前言 最近在搞一个博客,是托管在github和gitcafe上的,利用Hexo生成的.之后,发现一个问题,显示的分类都是一级的.而我想要的是:能显示多级分类,层次分明`的那样. 问题 基本主题自带的分 ...
- 基于DevExpress的Winform程序安装包的制作
在我们做系统开发的时候,都会面临一个安装包制作的问题,如何把我们做好的系统,通过安装包工具整合成一个安装包给客户进行安装.安装包的优势就是一步步安装就可以了,不用复制一大堆文件给客户,还怕缺少那个文件 ...
- C#开发微信门户及应用(43)--微信各个项目模块的定义和相互关系
我们在开发微信相关的应用的时候,一般需要完善的基础模块支持,包括微信公众号,微信企业号,以及一些业务模块的支持,一般随着功能的增多,我们需要非常清晰的界定他们的关系.模块的分拆以及合并往往需要考虑的代 ...
- css3 翻转和旋转的区别
我以前一直以为旋转跟翻转一样,今日自己旋转了好久都发觉跟翻转差一点点,纠结了十几分钟才明白,只能怪自己的立体感太差了. css3中的transform中有旋转,放缩,倾斜,平移的功能,分别对应的属性是 ...
- C# MVC绑定 List<DapperRow>到bootstrap-table列表
1.Dapper返回List<dynamic>对象 /// <summary> /// 获取候选人推荐的分页数据 /// </summary> /// <pa ...
- JFreechart在linux下不显示及中文乱码问题
一.使用JFreeChart建的报表,在window下能正常显示,但是放到linux下就报错,而且有时候会把tomcat挂掉, 原因是jfreechart的在linux系统中需要访问java awt库 ...
- onclick标签变成小手状
style=“cursor: pointer;”
- qam 64的设计
module qam64(x,out,clk,clk1,rst);input x,clk,clk1,rst;output [18:0] out;reg [2:0] count;reg [5:0] re ...
- 十一个行为模式之访问者模式(Visitor Pattern)
定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...