調用約定 調用約定(Calling convention)決定如下內容:函數參數的壓棧順序,由調用者仍是被調用者把參數彈出棧,以及產生函數修飾名的方法。MFC支持如下調用約定: _cdecl 按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對於「C」函數或者變量,修飾名是在函數名前加。對於「C++」函數,有所不一樣。 如函數void test(void)的修飾名是_test;對於不屬於一個類的「C++」全局函數,修飾名是?test@@ZAXXZ。 這是MFC缺省調用約定。因爲是調用者負責把參數彈出棧,因此能夠給函數定義個數不定的參數,如printf函數。 _stdcall 按從右至左的順序壓參數入棧,由被調用者把參數彈出棧。對於「C」函數或者變量,修飾名覺得前綴,而後是函數名,而後是符號「@」及參數的字節數,如函數int func(int a, double b)的修飾名是_func@12。對於「C++」函數,則有所不一樣。 全部的Win32 都遵循該約定。 _fastcall 頭兩個DWORD類型或者佔更少字節的參數被放入ECX和EDX,其餘剩下的參數按從右到左的順序壓入棧。由被調用者把參數彈出棧,對於「C」函數或者變量,修飾名以「@」爲前綴,而後是函數名,接着是符號「@」及參數的字節數,如函數int func(int a, double b)的修飾名是@func@12。對於「C++」函數,有所不一樣。 將來的編譯器可能使用不一樣的來存放參數。 thiscall 僅僅應用於「C++」成員函數。this指針存放於CX,參數從右到左壓棧。thiscall不是關鍵詞,所以不能被程序員指定。 naked call 採用1-4的調用約定時,若是必要的話,進入函數時編譯器會產生代碼來保存ESI,EDI,EBX,EBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。naked call不產生這樣的代碼。 naked call不是類型修飾符,故必須和_declspec共同使用,以下: __declspec( naked ) int func( formal_parameters ) { // Function body } 過期的調用約定 原來的一些調用約定能夠再也不使用。它們被定義成調用約定_stdcall或者_cdecl。例如: #define CALLBACK #define WINAPI #define WINAPIV #define APIENTRY WINAPI #define APIPRIVATE #define PASCAL __stdcall