stdcall 與 cdecl 的區別

2021-05-02 07:31:10 字數 877 閱讀 3292

幾乎我們寫的每乙個windows api函式都是__stdcall型別的,首先,需要了解兩者之間的區別: windows的函式呼叫時需要用到棧(stack,一種先入後出的儲存結構)。當函式呼叫完成後,棧需要清除,這裡就是問題的關鍵,如何清除??如果我們的函式使用了_cdecl,那麼棧的清除工作是由呼叫者,用com的術語來講就是客戶來完成的。這樣帶來了乙個棘手的問題,不同的編譯器產生棧的方式不盡相同,那麼呼叫者能否正常的完成清除工作呢?答案是不能。如果使用__stdcall,上面的問題就解決了,函式自己解決清除工作。所以,在跨(開發)平台的呼叫中,我們都使用__stdcall(雖然有時是以winapi的樣子出現)。那麼為什麼還需要_cdecl呢?當我們遇到這樣的函式如fprintf()它的引數是可變的,不定長的,被呼叫者事先無法知道引數的長度,事後的清除工作也無法正常的進行,因此,這種情況我們只能使用_cdecl。到這裡我們有乙個結論,如果你的程式中沒有涉及可變引數,最好使用__stdcall關鍵字。

另:_cdecl

按從右至左的順序壓引數入棧,由呼叫者把引數彈出棧。對於「c」函式或者變數,修飾名是在函式名前加下劃線。對於「c++」函式,有所不同。

如函式void test(void)的修飾名是_test;對於不屬於乙個類的「c++」全域性函式,修飾名是?test@@zaxxz

。這是mfc預設呼叫約定。由於是呼叫者負責把引數彈出棧,所以可以給函式定義個數不定的引數,如printf函式。

stdcall 和pascal一樣,都是pascal的呼叫習慣

按從右至左的順序壓引數入棧,由被呼叫者把引數彈出棧。對於「c」函式或者變數,修飾名以下劃線為字首,然後是函式名,然後是符號「@」及引數的位元組數,如函式int func(int a, double b)的修飾名是_func@12

。對於「c++」函式,則有所不同。

stdcall 與 cdecl 的區別

stdcall 與 cdecl 的區別 幾乎我們寫的每乙個windows api函式都是 stdcall型別的,首先,需要了解兩者之間的區別 windows的函式呼叫時需要用到棧 stack,一種先入後出的儲存結構 當函式呼叫完成後,棧需要清除,這裡就是問題的關鍵,如何清除?如果我們的函式使用了 c...

stdcall與cdecl的區別

1 區別vc 的c c 函式有兩種基本的呼叫約定 stdcall cdecl stdcall cdecl 函式 cint stdcalladds int a,int b int cdecladdc int a,int b asm32 push ebp mov ebp,esp sub esp,40h ...

stdcall與 cdecl的區別

1 stdcall是pascal程式的預設呼叫方式,通常用於win32 api中,函式採用從右到左的壓棧方式,自己在退出時清空堆疊。vc將函式編譯後會在函式名前面加上下劃線字首,在函式名後加上 和引數的位元組數。int f void p f 4 在外部組合語言裡可以用這個名字引用這個函式 2 c呼叫...