日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数调用规范__cdecl和__stdcall的区别

發(fā)布時間:2025/3/12 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数调用规范__cdecl和__stdcall的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
原作:葡萄架上的牽牛花 原地址:http://blog.bcchinese.net/happyjet/archive/2005/05/24/22545.aspx
__cdecl __stdcall
CC++程序的缺省調(diào)用規(guī)范 為了使用這種調(diào)用規(guī)范,需要你明確的加上__stdcall(或WINAPI)文字。即return-type__stdcallfunction-name[(argument-list)]
調(diào)用函數(shù)(Callee)返回,由調(diào)用方(Caller)調(diào)整堆棧。 1. 調(diào)用方的函數(shù)調(diào)用 ????????????????????????????????????????? 2. 被調(diào)用函數(shù)的執(zhí)行 3. 被調(diào)用函數(shù)的結(jié)果返回 4. 調(diào)用方清除調(diào)整堆棧 ????????????????????????????????? ?????????????????????????????? 調(diào)用函數(shù)(Callee)返回,由調(diào)用函數(shù)(Callee)調(diào)整堆棧。圖示: 1. 調(diào)用方的函數(shù)調(diào)用 2. 被調(diào)用函數(shù)的執(zhí)行 3. 被調(diào)用函數(shù)清除調(diào)整堆棧 4. 被調(diào)用函數(shù)的結(jié)果返回???????????????? ????????????????????????????????? ???????
因為每個調(diào)用的地方都需要生成一段調(diào)整堆棧的代碼,所以最后生成的文件較大。 因為調(diào)整堆棧的代碼只存在在一個地方(被調(diào)用函數(shù)的代碼內(nèi)),所以最后生成的文件較小。
函數(shù)的參數(shù)個數(shù)可變(就像printf函數(shù)一樣),因為只有調(diào)用者才知道它傳給被調(diào)用函數(shù)幾個參數(shù),才能在調(diào)用結(jié)束時適當(dāng)?shù)卣{(diào)整堆棧。 函數(shù)的參數(shù)個數(shù)不能是可變的。
對于定義在C程序文件中的輸出函數(shù),函數(shù)名會保持原樣,不會被修飾。 對于定義在C++程序文件中的輸出函數(shù),函數(shù)名會被修飾, MSDNUnderscore character (_) is prefixed to names. 我實際測試(VC4VC6)下來發(fā)現(xiàn)好像不是那么簡單。 可通過在前面加上extern C以去除函數(shù)名修飾。也可通過.def文件去除函數(shù)名修飾。 不論是C程序文件中的輸出函數(shù)還是C++程序文件中的輸出函數(shù),函數(shù)名都會被修飾。 對于定義在C程序文件中的輸出函數(shù),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++程序文件中的輸出函數(shù),好像更復(fù)雜,和__cdecl的情況類似。 好像只能通過.def文件去除函數(shù)名修飾。
_beginthread需要__cdecl的線程函數(shù)地址 _beginthreadexCreateThread需要__stdcall的線程函數(shù)地址
兩者的參數(shù)傳遞順序都是從右向左。 為了讓VB可以調(diào)用,需要用__stdcall調(diào)用規(guī)范來定義C/C++函數(shù)。請參看Microsoft KB153586 文章:How To Call C Functions That Use the _cdecl Calling Convention 當(dāng)你LoadLibrary一個DLL文件后, 把GetProcAddress取得的函數(shù)地址傳給上面三個線程生成函數(shù)時,請務(wù)必確認(rèn)實際定義在DLL文件的輸出函數(shù)符合調(diào)用規(guī)范要求。否則,編譯成Release版后運行,可能會破壞堆棧,程序行為不可預(yù)測。 VC中的相關(guān)編譯開關(guān):/Gd /Gr /Gz。另外,VC6中新增加的 /GZ 編譯開關(guān)可以幫你檢查堆棧問題。 我也是初學(xué)者,若有不對的地方、可以補充的地方,請指教。謝謝。?
(補充)匯編語言視點的比較文章: Intel x86 Function-call Conventions - Assembly View?

總結(jié)

以上是生活随笔為你收集整理的函数调用规范__cdecl和__stdcall的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。