在C++中定義回調函數(shù)時經常用到下列語句:
typedef void (CALLBACK *callbackfun) (param1, param2, ... , paramN)
在自己寫的方法去調用回調函數(shù)時,編譯器報錯。后來發(fā)現(xiàn)是方法中缺少了相應的宏定義WINAPI,正確的定義為:
void WINAPI caller(callbackfun myfun1, param2, ... , paramN)
其中,WINAPI和CALLBACK是windows自帶的宏定義:
#define CALLBACK __stdcall
#define WINAPI __stdcall
兩者的本質是一樣的。_stdcall是一種堆棧調用方式,該方式約定函數(shù)參數(shù)按照從右到左的順序入棧,被調用的函數(shù)在返回前清理傳送參數(shù)的棧,函數(shù)參數(shù)個數(shù)固定。而c++的缺省調用方式是_cdcel,這樣出錯的原因就很明顯了,回調函數(shù)和caller函數(shù)使用了不同調用方式,導致程序無法通過編譯。
那么什么時候使用_cdcel和_stdcall呢?
- 在默認情況下,采用__cdecl方式,因此可以省略.
- WINAPI一般用于修飾動態(tài)鏈接庫
- CALLBACK僅用于修飾回調函數(shù)