#define offset_of(type, member)   ((unsigned int)&((type*)0)->member)
#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offset_of(type, member)))

offset_of(type, member)

用途: 用于获取获取结构体某一个成员在该结构体中的位置

参数1:type ,表示结构体的类型

参数2:member  表示结构体成员

分析:

(unsigned int)  & (type*)0)->member   a.把值为0的指针强制转换成该结构体类型

                 b.通过该指针找到该成员
                    c.获取该成员相对于0 的地址偏移
                 d.强转成整形
 

container_of(ptr, type, member)

用途: 知道结构体中某一个成员的地址,需要获取到整个结构体的指针,通过该指针获取其他成员变量的数据

参数1:ptr,某一个成员的地址

参数2:type  结构体类型

参数3:member 该成员的名字

分析:

(type *)((char *)(ptr) - offset_of(type, member))

                  a.获取该成员相对于结构体指针的偏移

                 b.将该成员的地址转换成char*类型,该指针指向1byte的数据
                    c.转换成结构体类型的指针
                 d.使用该结构体成员的指针 - 该成员相对于结构体指针的偏移 = 结构体指针
 
 

注意事项:

使用gcc编译的时候有遇到此问题:warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
这是一个编译器警告,指示在某一行代码中进行了从指针到整数的类型转换,而且这两者的大小不同。
 (unsigned int)  & (type*)0)->member 中,由于我是在32位单片机中使用,所以unsigned int与地址长度相同。
如果在其他不同的系统中需注意该指针的强制转换问题,可以使用uintptr_t来解决跨平台的问题。
该类型定义在c库<stdint.h>中
 

关于函数宏offset_of 和 container_of的学习的更多相关文章

  1. C语言基础知识:几种特殊的函数宏封装方式

    函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销. 函数宏本质上为宏,可以直接进行定义,例如: #define INT ...

  2. PROCESS_YIELD()宏使用及过程分析<contiki学习笔记之八>

    好吧,昨晚上研究了switch()的底层实现原理--发现它并不是一般C语言教科书上那样所言,当然,这对于本身就非常熟悉汇编的同学来说,是小菜一碟.世界上,很多事情是巧合与必然的结合体,没有无缘无故的爱 ...

  3. Flask jinja2 全局函数,宏

    内置全局函数 dict()函数,方便生成字典型变量 {% set user = dict(name='Mike',age=15) %} <p>{{ user | tojson | safe ...

  4. JavaScript 引入方式 语言规范 语言基础 数据类型 常用方法 数组 if_else 比较运算符 for while 函数 函数的全局变量和局部变量 {Javascript学习}

    Javascript学习 JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript ...

  5. 使用函数计算三步实现深度学习 AI 推理在线服务

    目前深度学习应用广发, 其中 AI 推理的在线服务是其中一个重要的可落地的应用场景.本文将为大家介绍使用函数计算部署深度学习 AI 推理的最佳实践,  其中包括使用 FUN 工具一键部署安装第三方依赖 ...

  6. 函数:lambda表达式 - 零基础入门学习Python021

    函数:lambda表达式 让编程改变世界 Change the world by program lambda表达式 Python允许使用lambda关键字来创建匿名函数.我们提到一个新的关键字:匿名 ...

  7. 函数:内嵌函数和闭包 - 零基础入门学习Python020

    函数:内嵌函数和闭包 让编程改变世界 Change the world by program 内嵌函数和闭包 接下来这两节课我们谈的话题可能会"比较高级",所以如果是零基础的朋友, ...

  8. Delphi内存操作API函数(备查,并一一学习)

    Delphi内存操作API函数System.IsMemoryManagerSet;System.Move;System.New;System.ReallocMem;System.ReallocMemo ...

  9. 函数响应式编程及ReactiveObjC学习笔记 (-)

    最近无意间看到一个视频讲的ReactiveObjC, 觉得挺好用的 但听完后只是了解个大概. 在网上找了些文章, 有的写的比较易懂但看完还是没觉得自己能比较好的使用RAC, 有的甚至让我看不下去 这两 ...

  10. UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图 分类: iOS学习-UI 2015-07-02 22:09 68人阅读 评论(0) 收藏

    UI程序的一般执行顺序: 先进入main里面,执行函数UIApplicationMain(),通过该函数创建应用程序对象和指定其代理并实现监听,当执行函数UIApplicationMain()时还会做 ...

随机推荐

  1. LR_GD_MSE (公式补充)

    上篇是先撸了一把梯度下降的代码, 用来优先 LR 中的 MSE. 核心代码是在求解梯度这一步. # y = wx + b def step_gradient(b_current, w_current, ...

  2. MACD的价值不在于“金叉死叉”而在于背离

    之前我们根据MACD金叉死叉技术指标作为依据对股票进行买入和卖出操作,但由于MACD本身是由均线衍化而来的技术指标,具有一定的滞后性.也正是由于它的滞后性和单一性,通过MACD金叉死叉来进行买卖时,并 ...

  3. Git 中的“撤销”

    (1)当commit 完后,发现少add几个文件,可以: $ git commit -m 'initial commit' $ git add forgotten_file $ git commit ...

  4. HarmonyOS运动开发:如何绘制运动速度轨迹

    前言 在户外运动应用中,绘制运动速度轨迹不仅可以直观地展示用户的运动路线,还能通过颜色变化反映速度的变化,帮助用户更好地了解自己的运动状态.然而,如何在鸿蒙系统中实现这一功能呢?本文将结合实际开发经验 ...

  5. JS/Jquery检查网络路径文件是否存在

    var url='网络文件路径'; var isExists; $.ajax(url, { type: 'HEAD', dataType: 'text', async: false, success: ...

  6. PLsql and 汉化包的安装使用

    一.准备工作 1.点击下载PLSQL,本次安装的PLSQL版本为12.0.7,建议安装64位. 2.下载PLSQL时,版本旁边会有个"Language pack"的链接,点击后左侧 ...

  7. Qt项目转Visual Studio项目

    有时觉得在Qt中调试代码不够方便,无法调试更深层次的参数,故需要将Qt项目转为Visual Studio项目. 方法:qmake -tp vc Hello.pro 以上命令会将名为Hello的Qt工程 ...

  8. win10将python打包成apk详细文档

    打包不支持windows所以可以找一台linux的电脑 或者用win10子系统(推荐) 我用的是Ubuntu 方法:https://www.jianshu.com/p/fcf21d45ea74 我简单 ...

  9. 乒乓球测距(K210)

    测距 说明 识别的物体是乒乓球(规格应该是统一的吧), 硬件是K210,测距的函数经过拟合,在50cm范围内是准确的 如果使用起来不准确,可以打印代码中的LM, 然后去测数据,自己再拟合一个函数,代替 ...

  10. cosbench工具使用方法

    一.Cosbench工具介绍 cosbench是intel开源的针对对象存储开发的测试工具 二.Cosbench安装 运行环境: 这里我们的系统是Centos7.6 依赖软件: JDK nmap-nc ...