safecall,stdcall:調用的區別﹗ ( 积分: 50 )

  • 主题发起人 主题发起人 John_
  • 开始时间 开始时间
J

John_

Unregistered / Unconfirmed
GUEST, unregistred user!
safecall,stdcall:調用的區別﹗

function vartosql(value:Variant):String;stdcall;
function vartosql(value:Variant):String;safecall;

這兩者有什么區別呢﹖
 
safecall,stdcall:調用的區別﹗

function vartosql(value:Variant):String;stdcall;
function vartosql(value:Variant):String;safecall;

這兩者有什么區別呢﹖
 
The safecall convention must be used for declaring dual-interface methods.
 
stdcall和safecall在调用上基本一样,指定参数的入栈方式为从右到左,不使用寄存器,被调用者清空栈。
dll中一般都应声明为stdcall,需要和别的语言开发的程序交互时也应声明为stdcall。
因为Windows本身就是从右到左入栈
而Pascal是寄存器保存参数,或从左到右入栈
使用safecall调用规范时,系统封装了必要的异常防火墙。
相当于在stdcall的基础上加了try异常处理
 
Borland的注释

调用约定


声明过程或函数时,可以指定调用约定(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位应用程序中没有影响,仅维持向后兼容。
 
多人接受答案了。
 

Similar threads

回复
0
查看
881
不得闲
S
回复
0
查看
855
SUNSTONE的Delphi笔记
S
S
回复
0
查看
783
SUNSTONE的Delphi笔记
S
I
回复
0
查看
1K
import
I
I
回复
0
查看
821
import
I
后退
顶部