首页
论坛
课程
招聘
[原创]Delphi中的参数传递约定概述
2008-6-3 17:48 6940

[原创]Delphi中的参数传递约定概述

2008-6-3 17:48
6940
《Delphi中的参数传递约定概述》

由于Delphi太好用了以至于大多数Delphi fans对Delphi约定都没什么认识...
抱歉其实大部分人的确是这样的
这里写下一篇浊文仅供大家参考-转载保留版权.谢谢大家支持

1.register-Delphi默认模式
参数传递模式...前三个数据.eax,edx,ecx...超过三个参数部分.放在堆栈传递
其他的方法和...和stdcall一样...函数自己恢复堆栈

按照这个传递模式,所以说..这样效果编译器会更容易优化一些?呵呵
procedure XorMemory(lpMemory: Pointer; bKey: BYTE; dwLen: DWORD);
begin
  while (dwLen > 0) do
  begin
    PBYTE(lpMemory)^ := PBYTE(lpMemory)^ xor bKey;
    Inc(PBYTE(lpMemory));
    Dec(dwLen);
  end;
end;

2.pascal-目前基本上不使用了

3.cdecl-C语言调用约定(从右向左压栈.调用者恢复堆栈)
这个模式在Delphi下是一个很争议的话题..
怎么说呢..比如说wsprintf等函数都是错误的翻译...
C\C++下是采用cdecl调用约定,而Delphi下全部翻译成stdcall模式...

而且C\C++总是配合可变参数一起使用的...
而Delphi下也是有可变参数标记的一般用户很少去关注如何使用罢了
具体看一下windows.pas
function wsprintf(Output: PChar; Format: PChar): Integer; stdcall;
这里的声明类型完全是错误的...如果想要和C一样的方式
function wsprintf(Output: PChar; Format: PChar): Integer; cdecl; varargs; external user32 name 'wsprintfA';

function  DbgPrint(Format:PChar): NTSTATUS; cdecl; varargs; external NtKernel name 'DbgPrint';
function  _snprintf(buffer: PChar; nsize: Integer; const fmt: PChar): Integer; cdecl; varargs; external NtKernel name '_snprintf';

自己单独写一个函数声明...即可...你可以变参调用了...
使用的时候...和C\C++下使用完全一样

这里有一个窍门...这样的函数我们如何声明函数类型?
找了大量的资料还是没招.不知道如何测试居然测试成功了...这叫啥?不知道
program Project2;

uses
  Windows;

//  注意看下面--cdecl varargs;之间是没有;号的
type
  TwsprintfA = function(Output: PAnsiChar; Format: PAnsiChar): Integer; cdecl varargs;

var
  fnwsprintfA: TwsprintfA;
  szBuffer: Array[0..MAX_PATH] Of Char;
begin
  @fnwsprintfA := GetProcAddress(LoadLibrary('user32'), 'wsprintfA');
  fnwsprintfA(szBuffer, 'Id: %s, Age: %d', 'Anskya', 18);
  MessageBox(0, szBuffer, 'By Anskya', 0);
end.


4.stdcall-标准调用约定(从右向左压栈.函数自己恢复堆栈)
这个...基本上api都是采用如此调用模式..编写动态运行库的
比较重要的约定

5.safecall-Delphi不支持..唉~牧龙鼠大牛抱歉我解决半天也没搞定
这个约定C\C++支持,其实和register约定出奇的相似.
支持传递参数的寄存器不一样.

[培训] 优秀毕业生寄语:恭喜id:一颗金柚子获得阿里offer《安卓高级研修班》火热招生!!!

收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 440
活跃值: 活跃值 (46)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
StarsunYzL 活跃值 2008-6-3 18:00
2
0
学习,一看到用ea、b、cx来传递参数的多半不是Delphi就是Broland C++
雪    币: 1940
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
小虾 活跃值 10 2008-6-3 18:09
3
0
关于函数调用约定网上已经有很多了,不过关于如何在Delphi中声明C的多变参数函数我还是首次看到,呵呵,学习一下。
雪    币: 31
活跃值: 活跃值 (228)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
靴子 活跃值 2008-6-4 20:02
4
0
谢谢 又学到一招
雪    币: 200
活跃值: 活跃值 (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lsuper 活跃值 2008-6-4 22:09
5
0
delphi 支持 safecall 啊,在对 com 的支持上就是用 safecall 做的。
游客
登录 | 注册 方可回帖
返回