__cdecl
__stdcall
c和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 編譯開關可以幫你檢查堆疊問題。
我也是初學者,若有不對的地方、可以補充的地方,請指教。謝謝。
(
函式呼叫規範 cdecl和
cdecl stdcallc 和c 程式的預設呼叫規範 為了使用這種呼叫規範,需要你明確的加上 stdcall 或winapi 文字。即 return type stdcallfunction name argument list 在被呼叫函式 callee 返回後,由呼叫方 caller 調整堆疊...
函式呼叫規範 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 返回後,由呼叫方...