linux内核 container_ofC语言之应用
之前在剖析内核链表的文章中就有说到这个 container_of宏展开后的应用技巧。
//offset(struct list , list);----->展开后((size_t) & (struct list *)0 -> list)//写清楚一点时这样://struct list *p = NULL ; &p->list ; 即是求p这个结构体指针的成员list的地址,只不过p是0//地址,从0地址开始计算list成员的地址,也就是成员list在结构体struct list中的偏移量//这个宏的作用就是求解MEMBER成员在TYPE中的偏移量//编译器不报错的原因是在编译阶段就已经知道结构体里每个成员的属性的相对偏移量了 ,//在代码中对结构体成员的访问其实最终 会被编译器转化为对其相对地址的访问//在代码运行期间,其实根本就没有变量名还有属性成员,有的也就只有地址。
//container_of最终结果返回的是第二个表达式的值,这里所谓的__mptr是一个中间的指针变量,其实就是list_head指针类型,被初始化为ptr//而我所说的这个ptr,就是我们要求的list_head中的节点地址,定义这样一个中间的指针变量其实考虑了很多因素//如果传参进来的是ptr++,会有副作用,就类似于(p++)+(p++)这样//而(char *)__mptr之所以要强制转换为char实质上是因为地址是以字节为单位的,而char的长度是一个字节//所以contain_of实质是两个地址相减的结果//__mptr是结构体中list_head节点的地址,offset宏求的是list_head节点在MEMBER在结构体中TYPE中的偏移量,那么//__mptr减去它所在结构体中的偏移量,就是结构体的地址了。
上代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #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 cona_t{ int i; int j; int v; char t[10]; unsigned short xy; }; struct cona_t ct; unsigned short xy; int main(int argc,char * argv[]) { int xy; struct cona_t * p; memset(&ct,0,sizeof(struct cona_t)); ct.i = ct.j = ct.v = 10; sprintf(ct.t,"%s","sdf"); ct.xy = 20; p = container_of(&ct.xy,struct cona_t,xy); printf("%s\n",p->t); return 0; }
运行结果:
从运行结果可以看出我们可以通过一个结构体指针去获取一个结构体本身的成员。
linux内核 container_ofC语言之应用的更多相关文章
- Linux内核--C语言中内嵌汇编 asm __volatile__
在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可 ...
- linux内核学习之一 简单c语言反汇编
(我是第一次发技术博客的菜鸟,恳请大家指导!!) 一 由简单c程序生成汇编代码 首先给出本次我们要反汇编的简单c语言程序:(够简单吧~) 在linux环境中使用下面的命令条件编译: 生成汇编文件sh ...
- Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7)
http://blog.chinaunix.net/uid-20543672-id-3157283.html Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3 ...
- linux内核中的C语言常规算法(前提:你的编译器要支持typeof和type)
学过C语言的伙伴都知道,曾经比较两个数,输出最大或最小的一个,或者是比较三个数,输出最大或者最小的那个,又或是两个数交换,又或是绝对值等等,其实这些算法在linux内核中通通都有实现,以下的代码是我从 ...
- C语言之linux内核实现位数高低位互换
linux内核实在是博大精深,有很多优秀的算法,我之前在工作中就遇到过位数高低位交换的问题,那时候对于C语言还不是很熟练,想了很久才写出来.最近在看内核的时候看到有内核的工程师实现了这样的算法,和我之 ...
- C语言之linux内核实现最大公约数算法
最大公约数算法,又称欧几里德算法,至今已有几千年的历史了.在我们开始学习C语言的时候最常用的算法就是辗转相除法,其实在linux内核中,内核也是使用这样的方法实现两数最大公约数的计算. 两个整数的最大 ...
- 嵌入式C语言自我修养 04:Linux 内核第一宏:container_of
4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...
- 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展
1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...
- C 语言代码风格之 Linux 内核代码风格
GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区:https://bbs.huaweicloud.com/b ...
随机推荐
- 高通开发笔记---yukon worknote
点击打开链接 daily buildhttp://android-ci-platform.cnbj.sonyericsson.net/job/daily_build_jb-mr2-yukon/DL-C ...
- XMPP(一)-openfire服务端的安装和搭建
XMPP全称:可扩展通讯和表示协议 简介:可扩展通讯和表示协议 (XMPP) 可用于服务类实时通讯.表示和需求响应服务中的XML数据元流式传输.XMPP以Jabber协议为基础,而Jabber是即时通 ...
- iOS中 CocoaPods Mac App的安装和使用 韩俊强的博客
CocoaPods Mac App的安装和使用 CocoaPods桌面应用版下载地址:https://cocoapods.org/app打开应用会提示你是否安装命令行工具,选择install就也可以在 ...
- 用API给用户添加职责
DECLARE lc_user_name VARCHAR2(100) := 'PRAJ_TEST'; lc_resp_appl_short_name VARCHAR2(100) := 'FND' ...
- java操作xml文件--修改节点
上一篇文章我介绍了SAX方法解析XML文件的过程,这篇文章讲解的内容是利用DOM方法修改XML文件的节点内容. 下面依然是首先贴出XML文件: <?xml version ...
- CSDN专访:大数据时代下的商业存储
原文地址:http://www.csdn.net/article/2014-06-03/2820044-cloud-emc-hadoop 摘要:EMC公司作为全球信息存储及管理产品方面的领先公司,不久 ...
- 初探linux子系统集之timer子系统(二)
想着博客中还没有翻译过一篇文章,虽然英文水平有限,但是借助google翻译慢慢地翻译出一篇文章也是不错的选择.那就来学习下hrtimer的文档吧,翻译的略搓,可以直接跳过这篇,这里仅作为学习的过程!^ ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(十):创建游戏逻辑
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- Ubuntu 12.04: How to enable root login
1. vi /etc/lightdm/lightdm.conf and add following modifications. greeter-show-manual-login=true allo ...
- Hive drop table卡住的问题
在hive中,show tables,create 等命令能正常执行,删除表drop table x时,会出现卡住的现象. 进入mysql, show variables like 'char%' 可 ...