[Windows編程] 使用API函數GetProcAddress的注意事項

來源:互聯網
上載者:User

Windows API 函數 GetProcAddress 被廣泛用於取得函數指標地址。 例如:

 

typedef BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);

 

pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProductInfo");

 

注意函數定義typedef 中的WINAPI, 它指定了函數的調用協議, 這部分是非常必要而且關鍵的,寫代碼的時候需要注意。

 

比如你要想取得標準C++運行庫(msvcrt.dll) 中的strcpy函數,函數定義就應該是:

typedef char * (__cdecl *pfnStrRChr)(const char *string, int c);

pSRS = (pfnStrRChR)GetProcAddress(hMSVCRT, "strrchr");

 

函數調用協議指定了函數參數的傳遞方式以及棧管理方式。如果你這裡不指定調用協議,編譯器會用預設的調用協議。 結果可能和DLL 函數原先指定協議的不同,函數被調用時會直接導致程式崩潰。

 

比較主流的函數調用方式有 _cdecl , _stdcall, _fastcall, _thiscall 。

_cdecl 是C語言預設的函數調用協議:所有參數從右至左依次入棧,棧中的參數由調用者清除。

_stdcall 是Pascal 語言的預設的函數調用協議,所有參數從右至左依次入棧,棧中的參數由被調用的函數在返回後清除。 Windows API 全部採用 _stdcall 方式, 上面例子中的WINAPI 其實就是 ___stdcall

#define WINAPI __stdcall
__fastcall 是前兩個(x86機器)或者4個(x64機器)參數由寄存器傳遞,其餘參數還是通過堆棧傳遞。 棧中的參數由被調用的函數在返回後清除。Borland Delphi, C++ Builder 預設使用這種調用方式。

_thiscall 和_stdcall 類似, 只是_thiscall 把類的this指標放在某個特定的寄存器中,比如Visual C++放在ECX中, Borland C++放在EAX中。

 

經比較,幾種調用協議存在挺大差異,所以GetProcAddress 得到的函數需要指定正確的調用協議。

 

--

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.