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 }