在使用windows完成端口时,会使用到CONTAINING_RECORD宏,该宏的作用就是:根据结构体中的某成员的地址来推算出该结构体整体的地址,相当于一个万能公式。
下面代码的注释中,讲解了该宏的实现原理。

#include <Windows.h>
#include <stdio.h>
int main()
{struct T{int a;int b;int c;};//CONTAINING_RECORD宏的作用就是根据结构体中的某成员的地址来推算出该结构体整体的地址。T t = { 1, 2, 3 };//假设我们知道T结构体中b的地址和名称,求t的指针T *pT = CONTAINING_RECORD(&t.b, T, b);printf("a:%d b:%d c:%d\n", pT->a, pT->b, pT->c);//CONTAINING_RECORD的定义://((type *)( (PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))//最后一部分(&((type *)0)->field) 将0(空指针)转成type,再取地址。//在本例中就是将空指针转成T*, 然后指向b这个变量, 然后再取地址。//这个操作的作用就是:假设T开始在0x000000内存位置上分配内存,在此基础上求b的内存地址,//这样等同于求得b的内存结构体对齐偏移量, 求得b的地址我们转成ULONG_PTR类型,//然后用实际b的内存地址减去b的结构体偏移量求得结构体首地址。////分解开来就是://这种情况是允许的。//这个大前提很重要!!!T *pTemp = (T*)0;//求b的内存地址,在结构体首地址为0的情况下b的内存地址其实就是自身的对齐大小偏移量!!!//CONTAINING_RECORD宏的核心!!!int *pB = &pTemp->b;ULONG_PTR Offset = (ULONG_PTR)pB; //转成数字, 就是b的偏移量。printf("b的偏移量:%d\n", Offset);//因为各个成员的地址是递增的,最后用实际b的地址减b的偏移量的到结构体首地址T *pFinal = (T*)(((char*)&t.b) - Offset);printf("T中a:%d b:%d c:%d\n", pFinal->a, pFinal->b, pFinal->c);return 0;
}

CONTAINING_RECORD宏的实现原理相关推荐

  1. 我对CONTAINING_RECORD宏的详细解释

    tfref 宏CONTAINING_RECORD的用处其实还是相当大的, 而且很是方便, 它的主要作用是: 根据结构体中的某成员的地址来推算出该结构体整体的地址! 下面从一个简单的例子开始说起: 我们 ...

  2. C++Windows下CONTAINING_RECORD宏的用法和详解

    [cpp] view plaincopy print? #include <Windows.h> #include <stdio.h> int main() { struct  ...

  3. 2020.9.9丨微生物多样性、宏基因组测序原理

    微生物多样性测序原理及案例解析 研究对象 人类:口腔.皮肤.粪便.肠道... 动物:瘤胃.肠道- 植物:菌根.内生菌... 历代测序原理 一代测序 双脱氧链终止法 正常的DNA碱基是四种脱氧核糖核苷酸 ...

  4. 魔兽时间 一键宏 输出的原理与笔记

    魔兽世界是支持插件的,而插件是可以获取到人物的技能状态怪物的状态与技能(参考WA插件输出提示)那么根据这个将人物状态与法术的数据怪物的数据(以什么形式)显示到界面上,技能可以绑定施法宏到指定按键上,再 ...

  5. char* wchat_t*互转 及 A2T, T2A宏及其实现原理

    char :单字节变量类型,表示ASCII码. wchar_t :宽字节变量类型,用于表示Unicode字符.在<string.h>定义为:typedef unsigned short w ...

  6. 微生物组—宏基因组分析专题培训7月开课啦!北京

    在广大粉丝的期待下,<生信宝典>联合<宏基因组>在2018年7月北京鼓楼推出<宏基因组分析专题培训>,为大家提供一条走进生信大门的捷径.为同行提供一个扩增子.宏基因 ...

  7. 微生物组——宏基因组分析专题培训开课啦!!!

    在广大粉丝的期待下,<生信宝典>联合<宏基因组>在2018年7月北京鼓楼推出<宏基因组分析专题培训>,大家提供一条走进生信大门的捷径.为同行提供一个扩增子实战分析学 ...

  8. C 语言编程 — 宏定义与预处理器指令

    目录 文章目录 目录 前文列表 宏 预处理器 预处理器指令 预处理器指令示例 预处理器指令运算符 宏定义 简单宏定义 带参数的宏定义 符号吞噬问题 使用 do{}while(0) 结构 预定义的宏 常 ...

  9. 字符串类型、结构体、共用体、枚举、container宏、内存来源

    一.C语言的字符串类型 1.C语言没有原生字符串类型 很多高级语言像java.C#等就有字符串类型,有个String来表示字符串,用法和int这些很像,可以String s1 = "linu ...

最新文章

  1. android运行exe没有反应,安卓最担心的事情发生了
  2. iOS开发UI篇—懒加载
  3. python函数使用易错点_大部分人都会忽略的Python易错点总结
  4. Linux终端字符颜色设置
  5. BZOJ 2818: Gcd 筛法
  6. 卷积神经网络只是一种全连接神经网络的特殊情况
  7. boost::fusion::as_deque用法的测试程序
  8. 刘子佼 mysql 下载_MySQL数据管理之备份恢复案例解析 23讲 Mysql备份恢复实战 视频教程...
  9. eclipse中修改内存
  10. Java中的命名参数
  11. Maven依赖的是本地工程还是仓库jar包?
  12. mysql 5.6 command line client闪退_MySQL 5.6 Command Line Client 点开闪退解决方法
  13. java 井字棋 人机_一个井字棋tictactoe游戏的java实现 | Soo Smart!
  14. (43) 讨论和通知
  15. SpringCloud Consul Config 配置中心 (二)
  16. 内核中的notification chain浅析
  17. 调查显示存储虚拟化技术尚需3到5年才能成熟
  18. IBM虚拟化全接触 实现从虚拟化到云端的数据中心
  19. 基于Selenium的Web UI自动化实现(java)
  20. win7下MyEclipse装Nutch1.7

热门文章

  1. selenium 如何解决网页信任证书的问题
  2. 开源一个前端试卷题页面
  3. 阿里巴巴任庚:数字城市建设的“两核三转和四横五纵”
  4. ESP32连接阿里云MQTT物联网平台
  5. 关于将URL中的特殊字符进行转码和解码
  6. 从小沉默寡言,如今做主播“一夜一套房”:不说话的人,一开口就已经赢了!...
  7. python中实现多路分支的最佳控制结构是_python程序设计答案
  8. 嫖一嫖显示器的Over drive (OD) 功能
  9. css位元素 after
  10. 《NJUPT》网络信息安全_期末PPT整理笔记