博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
container_of分析--可用good【转】
阅读量:6698 次
发布时间:2019-06-25

本文共 2709 字,大约阅读时间需要 9 分钟。

转自:

1.container_of宏

1> Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。
2>接口:
container_of(ptr, type, member) 
 ptr:表示结构体中member的地址
 type:表示结构体类型
 member:表示结构体中的成员
通过ptr的地址可以返回结构体的首地址
3> container_of的实现: 
#define container_of(ptr, type, member) ({      \   
 const typeof( ((type *)0)->member ) *__mptr = (ptr);    \  
  (type *)( (char *)__mptr - offsetof(type,member) );})  
其实它的语法很简单,只是一些指针的灵活应用,它分两步:
第一步,首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。
说明:typeof是GNU C对标准C的扩展,它的作用是根据变量获取变量的类型《typeof关键字在linux 内核中很常见》
第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。
关于offsetof的用法可。

2. 举例来说明container_of的使用

1>正确示例:

#include 
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})struct test_struct { int num; char ch; float f1; }; int main(void) { struct test_struct *test_struct; struct test_struct init_struct ={
12,'a',12.3}; char *ptr_ch = &init_struct.ch; test_struct = container_of(ptr_ch,struct test_struct,ch); printf("test_struct->num =%d\n",test_struct->num); printf("test_struct->ch =%c\n",test_struct->ch); printf("test_struct->ch =%f\n",test_struct->f1); return 0; }执行结果:jibo@jibo-VirtualBox:~/cv_work/work/list/container_of $ ./maintest_struct->num =12test_struct->ch =atest_struct->ch =12.300000

 

2>错误示例:

#include 
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) struct test_struct { int num; char ch; float f1; }; int main(void) { struct test_struct *test_struct; char real_ch = 'A'; char *ptr_ch = &real_ch; test_struct = container_of(ptr_ch,struct test_struct,ch); printf("test_struct->num =%d\n",test_struct->num); printf("test_struct->ch =%c\n",test_struct->ch); printf("test_struct->ch =%f\n",test_struct->f1); return 0; }执行结果为:jibo@jibo-VirtualBox:~/cv_work/work/list/container_of1 $ ./maintest_struct->num =0test_struct->ch =Atest_struct->ch =0.000000

 

注意,由于这里并没有使用一个具体的结构体变量,所以成员num和f1的值是不确定的。

转载于:https://www.cnblogs.com/sky-heaven/p/7130862.html

你可能感兴趣的文章
SQL基础教程
查看>>
POJ 3683 Priest John's Busiest Day(2-ST)
查看>>
Why std::binary_search of std::list works, sorta ...(转载)
查看>>
一起谈.NET技术,在MVC2.0使用Lodop为WEB打印提出完美解决方案
查看>>
瑞星2009:3大拦截2大防御功能主动遏制木马病毒
查看>>
Android RIL源码研究笔记 の ril (一)
查看>>
手动添加mysql服务
查看>>
javascirpt历史澄清误解基本概念特点编程语言web2.0网页javascript - javascirpt知识大全...
查看>>
Java多线程同步Synchronized使用分析
查看>>
[ mongoDB ] - mongoDB的基本操作
查看>>
gson-2.2.api简单
查看>>
大跃进和循序渐进
查看>>
纯后台生成highcharts图片有哪些方法?
查看>>
Oracle手边常用70则脚本知识汇总
查看>>
Creating Apps With Material Design —— Creating Lists and Cards
查看>>
GIS基础软件及操作(二)
查看>>
Underscore.js (1.7.0)-函数预览
查看>>
Why does pthread_cond_signal not work?【转】
查看>>
Category 的一些事
查看>>
AS 2.0新功能 Instant Run
查看>>