When you
declare a procedure or function, you can specify a calling convention
using one of the directives register, pascal, cdecl, stdcall,
and safecall. For example,
function
MyFunction(X, Y: Real): Real; cdecl;
...
Calling
conventions determine the order in which parameters are passed to the routine.
They also affect the removal of parameters from the stack, the use of registers
for passing parameters, and error and exception handling. The default calling
convention is register.
·The register and pascal conventions
pass parameters from left to right; that is, the leftmost parameter is
evaluated and passed first and the rightmost parameter is evaluated and passed
last. The cdecl, stdcall, and safecall conventions pass parameters
from right to left.
·For all conventions except cdecl, the
procedure or function removes parameters from the stack upon returning. With
the cdecl convention, the caller removes parameters from the stack when
the call returns.
·The register convention uses up to three
CPU registers to pass parameters, while the other conventions pass all
parameters on the stack.
·The safecall convention implements
exception firewalls. On Windows, this implements interprocess COM error
notification.
The table
below summarizes calling conventions.
Directive |
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 |
The
default register convention is the most efficient, since it usually
avoids creation of a stack frame. (Access methods for published properties must
use register.) The cdecl convention is useful when you call
functions from shared libraries written in C or C++, while stdcall and safecall
are recommended, in general, for calls to external code. On Windows, the
operating system APIs are stdcall and safecall. Other operating
systems generally use cdecl. (Note that stdcall is more efficient
than cdecl.)
The safecall
convention must be used for declaring dual-interface
methods. The pascal convention is maintained for backward compatibility.
For more information on calling conventions, see Program control.
The directives near, far, and export refer to calling conventions in 16-bit Windows programming. They have no effect in 32-bit applications and are maintained for backward compatibility only.
声明过程或函数时,可以指定调用约定(calling convention)。指定调用约定可以使用的指示字包括register、pascal、cdecl、stdcall以及safecall。例如,
function
MyFunction(X, Y: Real): Real; cdecl;
...
调用约定决定了传递给例程的参数的顺序,还影响参数从栈中的解除、参数传递时对寄存器的使用以及处理错误和异常等。缺省的调用约定是register。
·register和pascal约定自左向右传递参数;也就是说,最左边的参数最先求值并传递,最右边的参数最后求值并传递。cdecl、stdcall和safecall约定自右向左传递参数。
·除cdecl外,对其他所有的约定,过程和函数在返回时即从栈中删除参数。对cdecl约定,则由调用者在调用返回时从栈中删除参数。
·register约定最多可以使用三个CPU寄存器传递参数,而其他的约定都通过栈传递所有的参数。
·safecall约定实现了异常防火墙。在Windows中,这一实现在内部处理COM错误通知。
下表是调用约定的简要概括:
指示字 |
参数顺序 |
参数删除者 |
是否用寄存器传递参数? |
|
register |
从左到右 |
例程 |
是 |
|
pascal |
从左到右 |
例程 |
否 |
|
cdecl |
从右到左 |
调用者 |
否 |
|
stdcall |
从右到左 |
例程 |
否 |
|
safecall |
从右到左 |
例程 |
否 |
缺省的register约定是效率最高的,因为它通常避免了栈中新帧的创建。(对公布属性published properties的访问必需使用register约定。)调用来自用C或C++编写的共享库的函数时,cdecl约定是很有用的,而对外部代码的调用,一般而言,推荐使用stdcall和safecall约定。在Windows中,操作系统API函数使用的是stdcall和safecall约定。其他操作系统通常使用cdecl约定。(注意,stdcall约定比cdecl约定具有更高的效率。)
safecall约定必需用于声明双重接口的方法。pascal约定用于维持向后(旧版本)兼容。有关调用约定的更多信息,见程序控制。
指示字near、far和export属于16位Windows编程中的调用约定,它们在32位应用程序中没有影响,仅维持向后兼容。