C++函数调用方式(_stdcall, _pascal, _cdecl...)总结 收藏
C++函數(shù)調用方式(_stdcall, _pascal, _cdecl...)總結 收藏
__stdcall:
????? _stdcall 調用約定相當于16位動態(tài)庫中經(jīng)常使用的PASCAL調用約定。在32位的VC++5.0中PASCAL調用約定不再被支持(實際上它已被定義為__stdcall。除了__pascal外,__fortran和__syscall也不被支持),取而代之的是__stdcall調用約定。兩者實質上是一致的,即函數(shù)的參數(shù)自右向左通過棧傳遞,被調用的函數(shù)在返回前清理傳送參數(shù)的內存棧,但不同的是函數(shù)名的修飾部分(關于函數(shù)名的修飾部分在后面將詳細說明)。
_stdcall是Pascal程序的缺省調用方式,通常用于Win32 Api中,函數(shù)采用從右到左的壓棧方式,自己在退出時清空堆棧。VC將函數(shù)編譯后會在函數(shù)名前面加上下劃線前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。
_cdecl:
????? _cdecl c調用約定, 按從右至左的順序壓參數(shù)入棧,由調用者把參數(shù)彈出棧。對于傳送參數(shù)的內存棧是由調用者來維護的(正因為如此,實現(xiàn)可變參數(shù)的函數(shù)只能使用該調用約定)。另外,在函數(shù)名修飾約定方面也有所不同。
_cdecl是C和C++程序的缺省調用方式。每一個調用它的函數(shù)都包含清空堆棧的代碼,所以產(chǎn)生的可執(zhí)行文件大小會比調用_stdcall函數(shù)的大。函數(shù)采用從右到左的壓棧方式。VC將函數(shù)編譯后會在函數(shù)名前面加上下劃線前綴。是MFC缺省調用約定。
__fastcall:?
?????? __fastcall調用約定是"人"如其名,它的主要特點就是快,因為它是通過寄存器來傳送參數(shù)的(實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的參數(shù),剩下的參數(shù)仍舊自右向左壓棧傳送,被調用的函數(shù)在返回前清理傳送參數(shù)的內存棧),在函數(shù)名修飾約定方面,它和前兩者均不同。
_fastcall方式的函數(shù)采用寄存器傳遞參數(shù),VC將函數(shù)編譯后會在函數(shù)名前面加上"@"前綴,在函數(shù)名后加上"@"和參數(shù)的字節(jié)數(shù)。
thiscall:
?????? thiscall僅僅應用于"C++"成員函數(shù)。this指針存放于CX寄存器,參數(shù)從右到左壓。thiscall不是關鍵詞,因此不能被程序員指定。
naked call:
????? 采用1-4的調用約定時,如果必要的話,進入函數(shù)時編譯器會產(chǎn)生代碼來保存ESI,EDI,EBX,EBP寄存器,退出函數(shù)時則產(chǎn)生代碼恢復這些寄存器的內容。
naked call不產(chǎn)生這樣的代碼。naked call不是類型修飾符,故必須和_declspec共同使用。
另附:
關鍵字 __stdcall、__cdecl和__fastcall可以直接加在要輸出的函數(shù)前,也可以在編譯環(huán)境的Setting.../C/C++ /Code Generation項選擇。當加在輸出函數(shù)前的關鍵字與編譯環(huán)境中的選擇不同時,直接加在輸出函數(shù)前的關鍵字有效。它們對應的命令行參數(shù)分別為/Gz、/Gd和/Gr。缺省狀態(tài)為/Gd,即__cdecl。
要完全模仿PASCAL調用約定首先必須使用__stdcall調用約定,至于函數(shù)名修飾約定,可以通過其它方法模仿。還有一個值得一提的是WINAPI宏,Windows.h支持該宏,它可以將出函數(shù)翻譯成適當?shù)恼{用約定,在WIN32中,它被定義為__stdcall。使用WINAPI宏可以創(chuàng)建自己的APIs。
總結
以上是生活随笔為你收集整理的C++函数调用方式(_stdcall, _pascal, _cdecl...)总结 收藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vb字符串在内存中的分布?
- 下一篇: vc数据类型转换大全