日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

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

發(fā)布時(shí)間:2025/3/15 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++Windows下CONTAINING_RECORD宏的用法和详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
[cpp] view plaincopy print?
  • #include?<Windows.h>??
  • #include?<stdio.h>??
  • int?main()??
  • {??
  • ????struct?ABCD??
  • ????{??
  • ????????int?a;??
  • ????????int?b;??
  • ????????int?c;??
  • ????????int?d;??
  • ????};??
  • ????//CONTAINING_RECORD宏的作用就是根據(jù)結(jié)構(gòu)體??
  • ????//類型和結(jié)構(gòu)體中成員變量地址和名稱則可求出??
  • ????//該變量所在結(jié)構(gòu)體的指針??
  • ????ABCD?Abcd?=?{?1,?2,?3,?4?};??
  • ????//假設(shè)我們知道ABCD結(jié)構(gòu)體中b的地址和名稱求整個(gè)??
  • ????//b所在結(jié)構(gòu)體ABCD的指針??
  • ????ABCD?*pAbcd?=?CONTAINING_RECORD(?&Abcd.b,?ABCD,?b?);??
  • ????printf(?"求得ABCD中a:%d?b:%d?c:%d?d:%d\n",?pAbcd->a,?pAbcd->b,?pAbcd->c,?pAbcd->d?);??
  • ??
  • ????//這是如何做到的呢?我們來(lái)看看CONTAINING_RECORD的表達(dá)式:??
  • ????//((type?*)(?(PCHAR)(address)?-?(ULONG_PTR)(&((type?*)0)->field)))??
  • ????//我們看最后一部分(&((type?*)0)->field)將0空指針轉(zhuǎn)成type取地址在本例??
  • ????//就是將空指針轉(zhuǎn)成ABCD*然后指向b這個(gè)變量然后在取地址,這個(gè)操作的作用就是??
  • ????//假設(shè)ABCD開(kāi)始在0x000000內(nèi)存位置上分配內(nèi)存在此基礎(chǔ)上求b的內(nèi)存地址,說(shuō)白了??
  • ????//就是求得b的內(nèi)存結(jié)構(gòu)體對(duì)齊偏移量,OK求得b的地址我們轉(zhuǎn)成ULONG_PTR類型,然后用實(shí)際??
  • ????//b的內(nèi)存地址減去b的結(jié)構(gòu)體偏移量求得結(jié)構(gòu)體首地址。??
  • ????//即:??
  • ????printf(?"---詳解---\n"?);??
  • ????ABCD?*pTest?=(?ABCD*?)0;????//這種情況是允許的??
  • ????int?*pB?=?&pTest->b;?????//求b的內(nèi)存地址,在結(jié)構(gòu)體首地址為0的情況下b的內(nèi)存地址其實(shí)就是自身的對(duì)齊大小偏移量??
  • ????ULONG_PTR?Offset?=?(?ULONG_PTR?)pB;?//轉(zhuǎn)成數(shù)字??
  • ????printf(?"b的偏移量:%d\n",Offset?);??
  • ??????
  • ????//最后用實(shí)際b的地址減b的偏移量的到結(jié)構(gòu)體首地址??
  • ????ABCD?*pFinal?=?(?ABCD*?)(?(?(?char*?)&Abcd.b?)?-?Offset?);??
  • ????printf(?"求得ABCD中a:%d?b:%d?c:%d?d:%d\n",?pFinal->a,?pFinal->b,?pFinal->c,?pFinal->d?);??
  • ????return?0;??
  • }??
  • #include <Windows.h> #include <stdio.h> int main() {struct ABCD{int a;int b;int c;int d;};//CONTAINING_RECORD宏的作用就是根據(jù)結(jié)構(gòu)體//類型和結(jié)構(gòu)體中成員變量地址和名稱則可求出//該變量所在結(jié)構(gòu)體的指針ABCD Abcd = { 1, 2, 3, 4 };//假設(shè)我們知道ABCD結(jié)構(gòu)體中b的地址和名稱求整個(gè)//b所在結(jié)構(gòu)體ABCD的指針ABCD *pAbcd = CONTAINING_RECORD( &Abcd.b, ABCD, b );printf( "求得ABCD中a:%d b:%d c:%d d:%d\n", pAbcd->a, pAbcd->b, pAbcd->c, pAbcd->d );//這是如何做到的呢?我們來(lái)看看CONTAINING_RECORD的表達(dá)式://((type *)( (PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))//我們看最后一部分(&((type *)0)->field)將0空指針轉(zhuǎn)成type取地址在本例//就是將空指針轉(zhuǎn)成ABCD*然后指向b這個(gè)變量然后在取地址,這個(gè)操作的作用就是//假設(shè)ABCD開(kāi)始在0x000000內(nèi)存位置上分配內(nèi)存在此基礎(chǔ)上求b的內(nèi)存地址,說(shuō)白了//就是求得b的內(nèi)存結(jié)構(gòu)體對(duì)齊偏移量,OK求得b的地址我們轉(zhuǎn)成ULONG_PTR類型,然后用實(shí)際//b的內(nèi)存地址減去b的結(jié)構(gòu)體偏移量求得結(jié)構(gòu)體首地址。//即:printf( "---詳解---\n" );ABCD *pTest =( ABCD* )0; //這種情況是允許的int *pB = &pTest->b; //求b的內(nèi)存地址,在結(jié)構(gòu)體首地址為0的情況下b的內(nèi)存地址其實(shí)就是自身的對(duì)齊大小偏移量ULONG_PTR Offset = ( ULONG_PTR )pB; //轉(zhuǎn)成數(shù)字printf( "b的偏移量:%d\n",Offset );//最后用實(shí)際b的地址減b的偏移量的到結(jié)構(gòu)體首地址ABCD *pFinal = ( ABCD* )( ( ( char* )&Abcd.b ) - Offset );printf( "求得ABCD中a:%d b:%d c:%d d:%d\n", pFinal->a, pFinal->b, pFinal->c, pFinal->d );return 0; }

    測(cè)試結(jié)果:

    總結(jié)

    以上是生活随笔為你收集整理的C++Windows下CONTAINING_RECORD宏的用法和详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。