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\n", 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("详解\n");
29     tagCONTAINING_RECORD *pT = (tagCONTAINING_RECORD*)0;
30     char* pB = &pT->b;
31     ULONG_PTR offset = (ULONG_PTR)pB;
32     printf("b的偏移值%d\n", offset);
33     tagCONTAINING_RECORD *pF = (tagCONTAINING_RECORD*)(cb - offset);
34     printf("detail中a:%d b:%c c:%d d:%d\n", 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\n", t.a, t.b, t.c, t.d);
42     detail(&t.b);
43     printf("main2中a:%d b:%c c:%d d:%d\n", t.a, t.b, t.c, t.d);
44     getchar();
45     return 0;
46 }

猜你喜欢

转载自www.cnblogs.com/leochan007/p/11359914.html
今日推荐