函数指针: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;应该就可以调用带参数的。
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;
var CommandProc: function(id: interger): Integer of object; CommandProc2: function(str: string): Integer of object; {还有n个函数} begin if command='com1' then begin TMethod(CommandProc).Code := TMyObj.MethodAddress(Command); if Assigned(TMethod(CommandProc).Code) then Result := CommandProc(pt.pt1); end;如何将TMethod(CommandProc).Code的CommandProc用字符代替?? 这样就不用写那么多判断了,只需这样就可以了begin TMethod(Command).Code := TMyObj.MethodAddress(Command); if Assigned(TMethod(Command).Code) then Result := Command(pt.pt1); end;
使用自动化对象. 使用IDispatch.Invoke. 或简单地作: 使用函数指针(上面有人说过了.),参数类型为Open Array: type TFUNC=function (Params: Array of const):Variant; end; 实现: 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']);
[email protected]
begin
myproc(...);
end.
VB里的我知道,DELPHI里的我不懂(我刚学)
我真的晕了什么函数指针????
我要的是
procedure TForm1.Button2Click(Sender: TObject);
begin
DoCommand1('CommandOne');
//DoCommand1('CommandEx(9)'); 我要的是这句不出错,具体的看上面
end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
type
ty1 = procedure;
ty2 = procedure(s : string);
procedure pro1;
begin
ShowMessage('No params');
end;procedure pro2(s : string);
begin
ShowMessage(s);
end;procedure Triger1(p : pointer; S:string = '');
begin
if p = @pro1 then
ty1(p)
else
ty2(p)(s);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Triger1(@pro1);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
Triger1(@pro2,'Has Params');
end;end.
to jinhe(_寻) : 你的方法可以,但是对于多参数而且参数的类型又不同,就不能实现了!
我要从一个COM对象中调用一个方法,这个方法如果是由用户来输入的字串的话,我怎么才能调用呢?
你增加如下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;应该就可以调用带参数的。
但是,由于函数很多,而且每个函数的参数都是不同的,不知道怎么实现?是不是定义每个函数名呢?我的方法是这样的,但是很麻烦。如下:
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;
begin
if p = @pro1 then
ty1(p)
else
ty2(p)(s);
end;可以在这个函数里,判断地址,在进行类型转换
kiss2([email protected]):
比如 sin(x: double): double cos(x: double); double 可以归结为一种类型 D1 myfun1(x,y: double): double myfun2(x,y: double): double 可以归结为另一种类型 D2 以此类推。
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
procedure a;
procedure b;
procedure c;
procedure comm(co:TProcedure);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure tform1.a;
begin
showmessage('a');
end;procedure tform1.b;
begin
showmessage('b');
end;procedure tform1.c;
begin
showmessage('c');
end;procedure tform1.comm(co:TProcedure);
begin
co;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
comm(@tform1.a);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
comm(@tform1.b);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
comm(@tform1.c);
end;end.
因为可以直接用字符代替函数名,而对于@XXX这种格式不知道怎么转换为用字符来代替
CommandProc: function(id: interger): Integer of object;
CommandProc2: function(str: string): Integer of object;
{还有n个函数}
begin
if command='com1' then
begin
TMethod(CommandProc).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(CommandProc).Code) then Result := CommandProc(pt.pt1);
end;如何将TMethod(CommandProc).Code的CommandProc用字符代替??
这样就不用写那么多判断了,只需这样就可以了begin
TMethod(Command).Code := TMyObj.MethodAddress(Command);
if Assigned(TMethod(Command).Code) then Result := Command(pt.pt1);
end;
使用IDispatch.Invoke.
或简单地作:
使用函数指针(上面有人说过了.),参数类型为Open Array:
type
TFUNC=function (Params: Array of const):Variant;
end;
实现:
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']);
你写的实在是看不懂,能举个例子吗?
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,VType哪里来的??
还有如何将String转换为pointer类型?谢谢!
Args写错了,应该是Params,VType是Params[i]的成员.
String可以转化为PChar:
PChar(String1);
不知是不是你想要的.