1. 程式人生 > >delphi中register, pascal, cdecl, stdcall, safecall

delphi中register, pascal, cdecl, stdcall, safecall



注: 使用錯誤,或者在該加的地方沒有加,可能會出現"privileged instruction"錯誤,或者地址訪問錯誤。

常見的呼叫慣例有register, pascal, cdecl, stdcall, safecall。函式的呼叫管理決定了引數如何傳遞給子過程,並從堆疊中退出,以及暫存器在引數傳遞中的使用,錯誤和異常的處理。Delphi中預設的呼叫慣例是register。
1) register和pascal:引數從左向右傳遞,也就是說最左邊的引數最先求值並傳入,最右邊的引數最後求值和傳入。cdecl,stdcall和safecall則按從右向左方向。
2) 對於除cdecl之外的所有呼叫慣例,函式/過程在返回的時候要把堆疊中的引數退棧。對cdecl慣例,呼叫者在被呼叫的過程返回後執行引數退棧操作
3) register呼叫慣例最多能用3個CPU暫存器來傳遞引數,而其它呼叫慣例只能通過堆疊來傳遞引數
4) safecall呼叫慣例實現了異常的防火牆。在Windows上實現了跨程序的COM錯誤通知機制。
5) register呼叫效率最高,因為它避免了堆疊的建立。Delphi中published屬性必須是register。
6) cdecl常用於呼叫C/C++編寫的共享庫中的函式;但是,如果要呼叫外部程式碼,那麼一般要用stdcall和safecall
7) 在Windows上,系統的API都是stdcall和safecall

;在其它作業系統上通常用cdecl(注意:stdcall比cdecl效率要高)
8) 在dual-interface(雙介面)方法中必須用safecall慣例。
9) pascal慣例是為了向後相容;near/far/export用於16位Window程式設計中的函式呼叫,在32位的應用程式中不發揮作用,僅僅是為了向後相容。
下表進行了總結:

Calling conventions Parameter order Clean-up Passes parameters in registers?
register Left-to-right Routine Yes
pascal Left-to-right Routine No
cdecl Right-to-left Caller No
stdcall Right-to-left Routine No
safecall Right-to-left Routine No

參考資料:Delphi幫助文件