contain_of宏定义
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。
实现方式:
container_of(ptr, type, member) ;
其实它的语法很简单,只是一些指针的灵活应用,它分两步:
第一步,首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。
第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。
其中的语法难点就是如何得出成员相对结构体的偏移量?
通过例子说明,如清单1:
#include <stdio.h>
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->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 ={,'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 ;
}
或者Linux内核中的函数:
struct eg2805_charger {
struct device *chg_dev;
struct i2c_client *client;
struct power_supply batt_psy;
struct power_supply *usb_psy;
struct workqueue_struct *chg_workqueue;
struct delayed_work chg_delay_work; bool enable_chg;
bool recharge;
unsigned int chg_type;
unsigned int battery_present;
unsigned int online;
unsigned int temperature;
unsigned int voltage;
unsigned int battery_status;
unsigned int ichg;
unsigned int aicr;
unsigned int cv_value;
unsigned int batt_current; struct qpnp_vadc_chip *vadc_dev; bool batt_hot;
bool batt_warm;
bool batt_cool;
bool batt_cold;
bool batt_good;
int usb_psy_ma;
struct mutex icl_set_lock;
}; static void eg2805_charger_work(struct work_struct *work)
{
u8 buf[50]={0};
int i=0;
int ret;
int temp, voltage;
int value = 0;
//第一个参数为work,函数传参下来的;第二个参数为定义的结构体,第三个则是传参下来的里面需要的work_struct
struct eg2805_charger *eg2805_chg = container_of(work,
struct eg2805_charger,
chg_delay_work.work);
contain_of宏定义的更多相关文章
- c++宏定义命令
在程序开始以#开头的命令,他们是预编译命令.有三类预编译命令:宏定义命令.文件包含命令.条件编译命令:今天聊聊宏定义: 宏定义命令将一个标识符定义为一个字符串,源程序中的该标识符均以指定的字符串来代替 ...
- dll导入导出宏定义,出现“不允许 dllimport 函数 的定义”的问题分析
建立dll项目后,在头文件中,定义API宏 #ifndef API_S_H #define API_S_H ...... #ifndef DLL_S_20160424 #define API _dec ...
- iOS之常用宏定义
下面我为大家提供一些常用的宏定义! 将这些宏定义 加入到.pch使用 再也不用 用一次写一次这么长的程序了 //-------------------获取设备大小------------------- ...
- linux中offsetof与container_of宏定义
linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->M ...
- Linux Kernel代码艺术——系统调用宏定义
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...
- 面试问题5:const 与 define 宏定义之间的区别
问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同 define宏是在预处理阶段展开: const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...
- 关于Xcode8.1 / iOS10+ 真机测试系统打印或者宏定义打印不显示问题
前言: 最近做项目时遇到了很多莫名其妙的问题,其中就有这个打印(NSLog).也不多废话了,我们先来回顾一下Xcode8发布以来,我们遇到的一些关于打印的问题,当然也有解决方法: 1.Xcode8打印 ...
- JDStatusBarNotification和一些宏定义
// // AddTopicViewController.m // vMeet2 // // Created by 张源海 on 16/6/30. // Copyright © 2016年 h ...
- #define宏定义形式的"函数"导致的bug
定义了一个宏定义形式的"函数": #define SUM8(YY)\ {\ int Y = YY>>2;\ ...\ } 然后使用的时候,传入了一个同名的变量Y: i ...
随机推荐
- 自学Zabbix3.5.6-监控项item-Value mapping值映射
zabbix为了显示更人性化的数据,在使用过程中,我们可以将获取到得数据映射为一个字符串.比如,我们写脚本监控MySQL是否在运行中, 一般返回0表示数据库挂了,1表示数据库正常,还有各种各样的监控都 ...
- json api
from flask import Flask, redirect, url_for, jsonify, request app = Flask(__name__) users = [] ''' RE ...
- div元素宽度不定的情况下如何居中显示
最近由于工作的原因碰到一个问题,就是在一个弹窗宽度不定的情况下还能是该弹窗居中显示,思考许久未找到合适办法,于是在网上找到一些办法在此总结记录下来方便以后的学习. 方法一:兼容IE67 <div ...
- intellij idea 在什么地方打开终端Terminal
File→Plugins→Terminal 勾选它,点击Apply,点击Restart即可如果是要启动terminal则必须先做完上面动作,才可以点击Tools→Open Terminal... 来达 ...
- 小白的Python之路 if __name__ == '__main__' 解析
if __name__ == '__main__' 参考文献: http://www.cnblogs.com/xuxm2007/archive/2010/08/04/1792463.html http ...
- 在 ReactNative 的 App 中,集成 Bugly 你会遇到的一些坑
一.前言 最近开新项目,准备尝试一下 ReactNative,所以前期做了一些调研工作,ReactNative 的优点非常的明显,可以做到跨平台,除了少部分 UI 效果可能需要对不同的平台进行单独适配 ...
- Angularjs 2 绝对零基础的教程(1):从安装配置开始
写在前面 适合人群: 1. 愿意未来从事前端工作,并以此开拓自己未来职业 2. 有任何一种编程语言基础 3. 喜欢简单粗暴学一门实用的技术,而不是做科研. Angular 2 比 Angular 1 ...
- Qt数据库集成应用封装
平时的大大小小的项目中,基本上都需要与数据库打交道,会遇到各种各样的应用场景,本人主要遇到四种场景1:数据库自动重连,例如mysql数据库中经常遇到服务器挂掉的情况,需要自动检测并重新连接数据库.2: ...
- touch事件应用
js的touch事件,一般用于移动端的触屏滑动: $(function(){ document.addEventListener("touchmove", _touch, fals ...
- jamup与gb2i组合
软件一定要开嗓单效果器,最好不要关闭中断软件/声音,每次有重新检测电流必须会有嗓音,最好用ipad ,不然会烦死人.默认delay太长,在DLY面板修改 gb2i 效果还行,他的价值重在使用,让新人使 ...