• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Code Knight

            Programming is so cool
            隨筆 - 52, 文章 - 0, 評論 - 14, 引用 - 0
            數據加載中……

            [轉]__cdecl和__stdcall的區別

            看到的不錯的學習文章,轉帖過來方便自己學習,無意侵犯作者。只當學習用

             

            __cdecl

             

             

            __stdcall

             

            C C++ 程序的缺省調用規范

             

            為了使用這種調用規范,需要你明確的加上 __stdcall (或 WINAPI )文字。即 return-type __stdcall function-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 編譯開關可以幫你檢查堆棧問題。

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

            posted on 2010-03-07 18:48 Code Knight 閱讀(1406) 評論(0)  編輯 收藏 引用 所屬分類: 跬步千里

            伊人久久综合无码成人网| 2020久久精品国产免费| 久久久久噜噜噜亚洲熟女综合| 亚洲午夜无码久久久久| 欧美一区二区久久精品| 香蕉久久夜色精品升级完成| 国产精品久久久久jk制服| 久久久久久久久久免免费精品| 婷婷国产天堂久久综合五月| 欧美亚洲色综久久精品国产| 久久精品国产精品国产精品污| 亚洲国产高清精品线久久 | 欧美激情精品久久久久久久| 久久天天躁夜夜躁狠狠躁2022| 91精品国产91久久久久福利| 久久香蕉综合色一综合色88| 日批日出水久久亚洲精品tv| 亚洲精品美女久久久久99| 久久精品国产72国产精福利| 精品国际久久久久999波多野| 一本久久a久久精品综合香蕉 | 亚洲精品白浆高清久久久久久| 久久超乳爆乳中文字幕| 久久亚洲国产精品123区| 国内精品久久久人妻中文字幕| 日批日出水久久亚洲精品tv| 国产精品免费福利久久| 国产毛片欧美毛片久久久| 亚洲第一永久AV网站久久精品男人的天堂AV | 97久久超碰国产精品2021| 久久精品国产精品亚洲人人| 久久精品成人免费看| 久久久久亚洲精品天堂| 人妻少妇久久中文字幕一区二区| 人妻精品久久久久中文字幕一冢本| 久久久WWW免费人成精品| 久久精品无码专区免费| 国产精品久久久久久久午夜片| 久久精品国产秦先生| 久久丫精品国产亚洲av不卡| 亚洲AV无码1区2区久久|