• vc_CONTAINING_RECORD使用


     1 #include <Windows.h>
     2 #include <stdio.h>
     3 struct tagCONTAINING_RECORD
     4 {
     5     int a;
     6     char b;
     7     int c;
     8     int d;
     9 };
    10 // 使用 CONTAINING_RECORD
    11 void test(char* cb)
    12 {
    13     tagCONTAINING_RECORD *t = CONTAINING_RECORD(cb, tagCONTAINING_RECORD, b);
    14     printf("test中a:%d b:%c c:%d d:%d
    ", t->a, t->b, t->c, t->d);
    15     t->a = 10;
    16 }
    17 // 详解
    18 //这是如何做到的呢?我们来看看CONTAINING_RECORD的表达式:
    19 //((type *)( (PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
    20 //我们看最后一部分(&((type *)0)->field)将0空指针转成type取地址在本例
    21 //就是将空指针转成ABCD*然后指向b这个变量然后在取地址,这个操作的作用就是
    22 //假设ABCD开始在0x000000内存位置上分配内存在此基础上求b的内存地址,说白了
    23 //就是求得b的内存结构体对齐偏移量,OK求得b的地址我们转成ULONG_PTR类型,然后用实际
    24 //b的内存地址减去b的结构体偏移量求得结构体首地址。
    25 
    26 void detail(char* cb)
    27 {
    28     printf("详解
    ");
    29     tagCONTAINING_RECORD *pT = (tagCONTAINING_RECORD*)0;
    30     char* pB = &pT->b;
    31     ULONG_PTR offset = (ULONG_PTR)pB;
    32     printf("b的偏移值%d
    ", offset);
    33     tagCONTAINING_RECORD *pF = (tagCONTAINING_RECORD*)(cb - offset);
    34     printf("detail中a:%d b:%c c:%d d:%d
    ", pF->a, pF->b, pF->c, pF->d);
    35     pF->c = 20;
    36 }
    37 int main()
    38 {
    39     tagCONTAINING_RECORD t = { 1,'a',3,4 };
    40     test(&t.b);
    41     printf("main1中a:%d b:%c c:%d d:%d
    ", t.a, t.b, t.c, t.d);
    42     detail(&t.b);
    43     printf("main2中a:%d b:%c c:%d d:%d
    ", t.a, t.b, t.c, t.d);
    44     getchar();
    45     return 0;
    46 }
  • 相关阅读:
    oracle单行函数 之 转换函数
    oracle单行函数 之 时间函数
    oracle单行函数 之 数字函数
    oracle单行函数 之 字符函数
    oracle 之 如何链接别人电脑的oracle
    轻应用介绍
    Web 目录枚举与遍历漏洞解决
    接口测试工具(Postman)
    Tomcat 编码不一致导致乱码
    持久化配置管理 diamond 使用简介
  • 原文地址:https://www.cnblogs.com/leochan007/p/11359914.html
Copyright © 2020-2023  润新知