比如我有一些函数(过程),我需要掉用他们,能不能通过函数名字符串来调用?有点儿象宏替换的意思!
以下的只能对于过程或不带参数的函数,如果函数带了参数就不能实现了,谁能解决??
type
{$M+}
TMyObj = class
published
function CommandOne: Integer;
// function CommandEx(i:integer): Integer; 这个带了参数就会出现错误
end;
{$M-}
function DoCommand1(const Command: string): Integer;
var
CommandProc: function: Integer of object;
begin
TMethod(CommandProc).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(CommandProc).Code) then Result := CommandProc;
end;
function TMyObj.CommandOne: Integer;
begin
result:=1;
end;
{function TMyObj.CommandEx(i:integer): Integer;
begin
result:=i;
end;}
procedure TForm1.Button2Click(Sender: TObject);
begin
DoCommand1('CommandOne');
//DoCommand1('CommandEx(9)'); 这个就会出错
end;
--
WBR, LVT.
PS: A second method by V.Titov :
uses
TypInfo;
type
TCommand = (CommandOne, CommandTwo, CommandThree, CommandFour);
function DoCommand2(const Command: string): Integer;
begin
Result := 0;
case TCommand(GetEnumValue(TypeInfo(TCommand), Command)) of
CommandOne: ..;
CommandTwo: ..;
CommandThree: ..;
CommandFour: ..;
end;
end;
*******************
回复人: chinalian(连长) ( ) 信誉:100 2002-4-20 14:08:16 得分:0
函数指针:
TVisitedEvent = function(FID: integer):integer of object;
你增加如下
function DoCommand2(const Command: string;id: integer): Integer;
var
CommandProc: function(id: interger): Integer of object;
begin
TMethod(CommandProc).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(CommandProc).Code) then Result := CommandProc(id); //注意参数
end;
应该就可以调用带参数的。
回复人: kiss2(kiss2@yeah.net) ( ) 信誉:110 2002-4-20 14:55:28 得分:0
thanks to chinalian(连长): 终于可以调用带参数的了。
但是,由于函数很多,而且每个函数的参数都是不同的,不知道怎么实现?是不是定义每个函数名呢?我的方法 是这样的,但是很麻烦。如下:
type
PTfuncjg = ^Tfuncjg;
Tfuncjg = record
pt1 : Integer;
pt2 : string;
{还有n个参数类型}
end;
function DoCommand2(const Command: string;pt: PTfuncjg): Integer;
var
CommandProc: function(id: interger): Integer of object;
CommandProc2: function(str: string): Integer of object;
{还有n个函数}
begin
new(pt);
if command='com1' then
begin
TMethod(CommandProc).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(CommandProc).Code) then Result := CommandProc(pt.pt1);
end;
if command='com2' then
begin
TMethod(CommandProc2).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(CommandProc2).Code) then Result := CommandProc2(pt.pt2);
end;
//这样如果有N个函数,就要写N次了,有没有办法更简单点,而且速度也快点
end;
回复人: chinalian(连长) ( ) 信誉:100 2002-4-20 17:01:40 得分:0
kiss2(kiss2@yeah.net):
你可以将N个函数根据不同的参数个数和参数类型归结为M类别,如:I2D1(代表前两个参数为integer,第 三个为double)等;然后,在function DoCommand2中增加一个参数指出为哪个类别,则只要针对这M个类别写 出不同的情况就可以了。有良好的设计的话,M应该不会大。比如
sin(x: double): double
cos(x: double); double
可以归结为一种类型 D1
myfun1(x,y: double): double
myfun2(x,y: double): double
可以归结为另一种类型 D2,以此类推。
回复人: plainsong(轻风) ( ) 信誉:100 2002-05-05 20:56:00 得分:0
不定参数
function MyFunc(Params: Array of const):Variant;
var
I: Integer;
begin
Result := '';
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger: ...
vtBoolean: ...
vtChar: ...
vtExtended: ...
vtString: ...
vtPChar: ...
vtObject: ...
vtClass: ...
vtAnsiString: ...
vtCurrency: ...
vtVariant: ...
vtInt64: ...
end;
end;
调用:
var
afunc:TFUNC;
begin;
afunc := GetFunc('MyFunc');
afunc([1,2.34,'abcde']);
GetFunc根据一个字符串返回一个TFUNC变量(函数指针);
afunc([1,2.34,'abcde']);是用一个整型、一个浮点型和一个字符串型参数去调用。
假设现在调用的是MyFunc:
在循环中:(i := 0 to 2)
i=0:VType=vtInteger,VInteger=1
i=1:VType=vtextended,VExtended^=2.34
i=2:VType=vtAnsiString,string(VAnsiString)='abcde'
详见TVarRec的帮助.
不过这种方法无法得到函数的参数信息,调用者必须保证参数匹配,或所有的函数都要能处理任意个数任意类型 的参数,更好的方法是使用Automation对象,由于内容太多,我就不多讲了,用Delphi编写Automation对象非赏容 易,调用也很容易,因为Delphi内置了对Automation对象的支持,可要按字符串调用反而要自己去做了,你可以看 一下MSDN中IDispatch的帮助.C++Builder由于没有Automation对象的内置支持,所以是用字符串来查找 Automation对象的方法的,反而容易实现你的要求.GetFunc由你自己去写;Args写错了,应该是Params,VType是Params[i]的成员.String可以转化为PChar:
PChar(String1);不知是不是你想要的.