函式呼叫規範 cdecl和

2021-05-22 17:33:38 字數 2561 閱讀 7517

__cdecl

__stdcallc

和c++

程式的預設呼叫規範

為了使用這種呼叫規範,需要你明確的加上

__stdcall

(或winapi

)文字。即

return-type

__stdcallfunction-name [(argument-list )]

呼叫函式

(callee)

返回,由呼叫方

(caller)

調整堆疊。

1. 呼叫方的函式呼叫

2. 被呼叫函式的執行

3. 被呼叫函式的結果返回

4. 呼叫方清除調整堆疊

呼叫函式

(callee)

返回,由呼叫函式

(callee)

調整堆疊。圖示:

1. 呼叫方的函式呼叫

2. 被呼叫函式的執行

3. 被呼叫函式清除調整堆疊

4. 被呼叫函式的結果返回

因為每個呼叫的地方都需要生成一段調整堆疊的**,所以最後生成的檔案較大。

因為調整堆疊的**只存在在乙個地方(被呼叫函式的**內),所以最後生成的檔案較小。

函式的引數個數可變(就像

printf

函式一樣),因為只有呼叫者才知道它傳給被呼叫函式幾個引數,才能在呼叫結束時適當地調整堆疊。

函式的引數個數不能是可變的。

對於定義在

c程式檔案中的輸出函式,函式名會保持原樣,不會被修飾。

對於定義在

c++程式檔案中的輸出函式,函式名會被修飾,

msdn

說underscore character (_) is prefixed to names

. 我實際測試(

vc4和

vc6)下來發現好像不是那麼簡單。

可通過在前面加上extern「c 」以去除函式名修飾。也可通過.def檔案去除函式名修飾。

不論是c程式檔案中的輸出函式還是

c++程式檔案中的輸出函式,函式名都會被修飾。

對於定義在

c程式檔案中的輸出函式,

an underscore (_) is prefixed to the name. the name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list.

對於定義在

c++程式檔案中的輸出函式,好像更複雜,和

__cdecl

的情況類似。

好像只能通過.def檔案去除函式名修飾。

_beginthread

需要__cdecl

的執行緒函式位址

_beginthreadex

和createthread

需要__stdcall

的執行緒函式位址

兩者的引數傳遞順序都是從右向左。

為了讓vb可以呼叫,需要用

__stdcall

呼叫規範來定義

c/c++

函式。請參看microsoft kb153586 文章:how to call c functions that use the _cdecl calling convention

。 當你

loadlibrary

乙個dll

檔案後, 把

getprocaddress

取得的函式位址傳給上面三個執行緒生成函式時,請務必確認實際定義在

dll檔案的輸出函式符合呼叫規範要求。否則,編譯成

release

版後執行,可能會破壞堆疊,程式行為不可**。

vc中的相關編譯開關:/gd /gr /gz 。另外,vc6 中新增加的/gz 編譯開關可以幫你檢查堆疊問題。

我也是初學者,若有不對的地方、可以補充的地方,請指教。謝謝。

(補充)組合語言視點的比較文章:

intel x86 function-call conventions - assembly view

函式呼叫規範 cdecl和

函式呼叫 規範 cdecl 和 stdcall的區別 一目了然 形式 原作 葡萄架上的牽牛花 cdecl stdcallc和 c 程式的預設呼叫規範 為了使用這種呼叫規範,需要你明確的加上 stdcall 或winapi 文字。即 return type stdcallfunction name a...

函式呼叫規範 cdecl和

原作 葡萄架上的牽牛花 cdecl stdcallc和 c 程式的預設呼叫規範 為了使用這種呼叫規範,需要你明確的加上 stdcall 或winapi 文字。即 return type stdcallfunction name argument list 在被呼叫函式 callee 返回後,由呼叫方...

函式呼叫規範 cdecl和

cdecl stdcall c和c 程式的預設呼叫規範 為了使用這種呼叫規範,需要你明確的加上 stdcall 或 winapi 文字。即 return type stdcallfunction name argument list 在被呼叫函式 callee 返回後,由呼叫方 caller 調整堆...