按名字调用方法高级解决方案

时间:2010-01-26 12:53:20  来源:第二电脑网  作者:第二电脑网

  第二电脑网导读:r />typeTProcedure = procedure(Test: string) of object;procedure ExecuteRoutine(Obj: TObject; Name, Param: string);varPMethod: TMethod;AProcedure: TProcedure;begin  PMethod.Data := Pointer(Obj);  PMethod.Code := Obj.MethodAddress(Name);  if Assigned(PMethod.Code) then
  正文:

名字调用方法似乎一直以来都是大家比较关注的技术,在论坛上有一个经典的答复:


type
TProcedure = procedure(Test: string) of object;

procedure ExecuteRoutine(Obj: TObject; Name, Param: string);
var
PMethod: TMethod;
AProcedure: TProcedure;
begin
  PMethod.Data := Pointer(Obj);
  PMethod.Code := Obj.MethodAddress(Name);
  if Assigned(PMethod.Code) then
  begin
    AProcedure := TProcedure(PMethod);
    AProcedure(Param);
  end;
end;

  使用:待调用方法声明为某个类的 published 方法,Obj 为拥有待调用方法的类的
实例,Name 和 Param 分别为待调用方法的名字和参数。

但是这个办法有一个很大的局限性:一旦 TProcedure 声明定了下来,待调用方法的参
数表也就一定了。要是我定义了多个待调用方法,且参数个数、类型、返回值均不同,
则这个办法也就无能为力了。另:用 GetProcAddress 代替 MethodAddress 也可以实
现类似的效果,不过我们今天讨论的是调用类的“方法”,而它所返回的不是“方法”,
因为 GetProcAddress 仅能取得应用程序的输出(exports)了的过程或函数,这些过
程或函数不属于任何类,也就称不上“方法”。当然,效果类似,但是局限也类似 :-(

那么要是参数的个数、类型均可变就无法解决了吗?(要是这样就不会有本文了)通过
研究,我发现了一种行之有效的办法:Format 函数(注意,不是 DOS 命令,呵呵)相
信大家都不陌生吧,传入它的参数的个数和类型不都是可变的吗?只要声明如下:


procedure AProc(Param: array of const);

即可这样调用:


AProc([123, 'X', True, 'hello'...]);

有朋友可能要说了,那不就简单了,这样不就可以了:


type
TProcedure = procedure(Params: array of const) of object;

procedure ExecuteRoutine(Obj: TObject; Name: string; Params: array of const);
var
...
begin
  ...
  AProcedure(Params);
  ...
end;

别急,问题才刚刚出现呢,你运行试一试?出问题了吧。(为方便起见,暂时称我们的
ExecuteRoutine 函数,为控制函数;待调用方法简称为待调方法)这个形参表的声明
办法的确适合我们的控制函数,但是不适合待调方法。为什么?因为待调方法的形参表
的确不是这样(array of const)的啊。当然了,你说你把所有待调方法的形参表都改
成这个样子不就可以了?且不说你需要改动多少东西(包括待调函数的参数表和内部实
现,关键是内部实现部分),就看看你改了过后的待调方法的形参表,全部都成了一个
模样。说不定到时候你自己都不知道到底应该传什么参数进去了。因此,我们应该尽量
保持待调方法的形参表。

现在问题转化为了在控制函数中已知待调方法的地址及其参数列表(存放在一个
TVarRec 的数组中),如何在调用它的时候将参数传进去。这需要几点预备知识:

  1. 首先我们来看看传进来的这个参数表:Params。它的类型被 Delphi 称作可变开
放数组(Variant open array),等价于 array of TVarRec,也就是说 Params 是一
个成员为 TVarRec 的数组。换句话说,在参数被传进 Params 的时候,各种类型都被
Delphi 自动转化为了 TVarRec(参见帮助中的 Variant open array parameters 一
节)。看一下 TVarRec 的定义可知,它实际储存的数据域为 4 Bytes,超过 4 Bytes
的只存指针,需要注意的是 TVarRec 的大小是 8 Bytes(经研究发现前 4 Bytes 存放
"按名字调用方法高级解决方案"由第二电脑网原创提供,转载请注明:http://www.002pc.com/master/College/Language/Delphi/12416.html

 1/4    1 2 3 4 下一页 尾页


关键字:

关于《按名字调用方法高级解决方案》文章的评论

站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td