如何调用指定类名的指定方法名

时间:2022-11-26 20:13:08
如果给定:CLASS的名称:var classname := 'TmyClass';
          方法名     :var functionname:= 'print';

如何调用TmyClass的print方法。

11 个解决方案

#1


好像不可能

#2


调用类的方法,应该先建立该类的一个实例,

对实例可以类型转换,楼主说的方式在delphi我没见过这样的做法,

这样对代码的动态控制,我只知道Tsql可以。

#3


type
  ta = class(TPersistent)
  published
    class function fa:string;
    class function fb(const i : Integer):string;
  end;
  TtestMethod = function (AObj : TObject) : string;
  TtestMethod2 = function (AObj : TObject; const i:Integer) : string;


............

{ ta }

class function ta.fa: string;
begin
  Result := 'fa.fa';
end;

class function ta.fb(const i: Integer): string;
begin
  Result  :=  IntToStr(i);
end;

procedure TMainForm.Button2Click(Sender: TObject);
var
  a : TClass;
  f : TtestMethod;
  f2 : TtestMethod2;
begin
  a :=  GetClass('Ta');
  if Assigned(a) then
  begin
    f :=  TtestMethod(a.MethodAddress('fa'));
    if Assigned(f) then
      ShowMessage(f(nil));
    f2 :=  TtestMethod2(a.MethodAddress('fb'));
    if Assigned(f2) then
      ShowMessage(f2(nil, 111));
  end;
end;

initialization
  RegisterClass(ta);
finalization
  UnregisterClass(ta);

end.

#4


注:上面的方法只能调用类方法,或普通方法中没有引用类成员的方法
如果引用了类成员,ShowMessage(f(nil))这里的nil必须改为类实例,否则会出不可预料的结果.
如果引用了类实例,则与楼主的要求不符.

#5


PS:方法只能是published的,也就是具有RTTI信息的才能用MethodAddress取得地址

#6


http://quester.blog.sohu.com/1895284.html

#7


我本来想做一个DELPHI的MVC的框架,需要使用“反射机制”来做。我会继续找这个方法,如果成功了,我将在本贴后面贴上的。谢谢大家

#8


如果你对ObjectPascal语法仔细研究,你会发现你的问题的本质是"根据一个类名字符串获得该类的类引用",获得类引用后操作就没问题了,你想调用该类的方法,如果是类方法,则在类上调用,如果是实例方法,则创建类实例后再调用.
现在问题的关键就是如何"根据一个类名字符串获得该类的类引用",这可能吗?
好象有点可能,前提是你需要调用的类已经定义,如果一个类没有定义,他的行为是未知的.下面的代码可能对你有点帮助(假设这个类是TButton,实际中可换成你自己定义的类):
Type 
  TBtnClass=Class of TButton;
var
  Btn:TButton;
begin
  RegisterClass(TButton);//向delphi注册类名,此处可换成你自己的类
  Btn:=TBtnClass(GetClass('TButton')).Create(self);//根据类名字符串获得类引用
  Btn.Parent:=self;
  Btn.SetBounds(10,10,60,20);
  Btn.Caption:="动态创建的按钮";
end;
这里十分关键的是你操作的类必须是已经定义并实现的,否则你无法向系统注册类名

#9


to sxqwhxq(步青云)::
要操作的类肯定已经实现了。
但是要一个方法的名称去调用这个类的方法,怎么实现呢?

#10


如果想通过方法名字符串去调用该方法,该方法是类方法,好象无法实现;如果该方法是位于published段,可以实现。
以下代码应该对你有帮助:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Sayhello;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  AMethod:TMethod;
  Proc:Procedure of object;
begin
  AMethod.Code:=self.MethodAddress('Sayhello');
  AMethod.Data:=self;
  TMethod(Proc):=AMethod;
  Proc;
end;
procedure Tform1.Sayhello;
begin
  ShowMessage('');
end;
可以结贴了

#11


谢谢,

#1


好像不可能

#2


调用类的方法,应该先建立该类的一个实例,

对实例可以类型转换,楼主说的方式在delphi我没见过这样的做法,

这样对代码的动态控制,我只知道Tsql可以。

#3


type
  ta = class(TPersistent)
  published
    class function fa:string;
    class function fb(const i : Integer):string;
  end;
  TtestMethod = function (AObj : TObject) : string;
  TtestMethod2 = function (AObj : TObject; const i:Integer) : string;


............

{ ta }

class function ta.fa: string;
begin
  Result := 'fa.fa';
end;

class function ta.fb(const i: Integer): string;
begin
  Result  :=  IntToStr(i);
end;

procedure TMainForm.Button2Click(Sender: TObject);
var
  a : TClass;
  f : TtestMethod;
  f2 : TtestMethod2;
begin
  a :=  GetClass('Ta');
  if Assigned(a) then
  begin
    f :=  TtestMethod(a.MethodAddress('fa'));
    if Assigned(f) then
      ShowMessage(f(nil));
    f2 :=  TtestMethod2(a.MethodAddress('fb'));
    if Assigned(f2) then
      ShowMessage(f2(nil, 111));
  end;
end;

initialization
  RegisterClass(ta);
finalization
  UnregisterClass(ta);

end.

#4


注:上面的方法只能调用类方法,或普通方法中没有引用类成员的方法
如果引用了类成员,ShowMessage(f(nil))这里的nil必须改为类实例,否则会出不可预料的结果.
如果引用了类实例,则与楼主的要求不符.

#5


PS:方法只能是published的,也就是具有RTTI信息的才能用MethodAddress取得地址

#6


http://quester.blog.sohu.com/1895284.html

#7


我本来想做一个DELPHI的MVC的框架,需要使用“反射机制”来做。我会继续找这个方法,如果成功了,我将在本贴后面贴上的。谢谢大家

#8


如果你对ObjectPascal语法仔细研究,你会发现你的问题的本质是"根据一个类名字符串获得该类的类引用",获得类引用后操作就没问题了,你想调用该类的方法,如果是类方法,则在类上调用,如果是实例方法,则创建类实例后再调用.
现在问题的关键就是如何"根据一个类名字符串获得该类的类引用",这可能吗?
好象有点可能,前提是你需要调用的类已经定义,如果一个类没有定义,他的行为是未知的.下面的代码可能对你有点帮助(假设这个类是TButton,实际中可换成你自己定义的类):
Type 
  TBtnClass=Class of TButton;
var
  Btn:TButton;
begin
  RegisterClass(TButton);//向delphi注册类名,此处可换成你自己的类
  Btn:=TBtnClass(GetClass('TButton')).Create(self);//根据类名字符串获得类引用
  Btn.Parent:=self;
  Btn.SetBounds(10,10,60,20);
  Btn.Caption:="动态创建的按钮";
end;
这里十分关键的是你操作的类必须是已经定义并实现的,否则你无法向系统注册类名

#9


to sxqwhxq(步青云)::
要操作的类肯定已经实现了。
但是要一个方法的名称去调用这个类的方法,怎么实现呢?

#10


如果想通过方法名字符串去调用该方法,该方法是类方法,好象无法实现;如果该方法是位于published段,可以实现。
以下代码应该对你有帮助:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Sayhello;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  AMethod:TMethod;
  Proc:Procedure of object;
begin
  AMethod.Code:=self.MethodAddress('Sayhello');
  AMethod.Data:=self;
  TMethod(Proc):=AMethod;
  Proc;
end;
procedure Tform1.Sayhello;
begin
  ShowMessage('');
end;
可以结贴了

#11


谢谢,