_stdcall _cdec區別

來源:互聯網
上載者:User

(1) _stdcall調用
  _stdcall是Pascal程式的預設調用方式,參數採用從右至左的壓棧方式,被調函數自身在返回前清空堆棧。
  WIN32 Api都採用_stdcall調用方式,這樣的宏定義說明了問題:

  #define WINAPI _stdcall

  按C編譯方式,_stdcall呼叫慣例在輸出函數名前面加底線,後面加“@”符號和參數的位元組數,形如。

(2) _cdecl調用
  _cdecl是C/C++的預設調用方式,參數採用從右至左的壓棧方式,傳送參數的記憶體棧由調用者維護。_cedcl約定的函數只能被C/C++調用,每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行檔大小會比調用_stdcall函數的大。

  由於_cdecl調用方式的參數記憶體棧由調用者維護,所以變長參數的函數能(也只能)使用這種呼叫慣例。關於C/C++中變長參數(…)的問題,筆者將另文詳述。

  由於Visual C++預設採用_cdecl 調用方式,所以VC中中調用DLL時,使用者應使用_stdcall呼叫慣例。
  按C編譯方式,_cdecl呼叫慣例僅在輸出函數名前面加底線,形如_functionname。

  (3) _fastcall調用
  _fastcall調用較快,它通過CPU內部寄存器傳遞參數。

  按C編譯方式,_fastcall呼叫慣例在輸出函數名前面加“@”符號,後面加“@”符號和參數的位元組數,形如@functionname@number。


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

轉載: http://blog.csdn.net/dengziliang001/article/details/17448789

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.