首页  编辑  

如何用函数名字符串来调用函数?

Tags: /超级猛料/Language.Object Pascal/内嵌汇编、函数、过程/   Date Created:

比如我有一些函数(过程),我需要掉用他们,能不能通过函数名字符串来调用?有点儿象宏替换的意思!

以下的只能对于过程或不带参数的函数,如果函数带了参数就不能实现了,谁能解决??

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);不知是不是你想要的.