



Oi amigos.
Está dica é mais avançada e também é um exemplo de uso da RTTI do Delphi.
Neste exemplo vamos executar um método de classe, sem declarar uses da unit onde está a classe e executar pelo nome do método.
Primeiramente vamos as explicações…
Passo 1
Para funcionar, a classe que detém o método deve ser descendente de TPersistent.
Exemplo:
TExemploClasse = class(TPersistent)
class function Teste(ANumber : Integer) : string;
end;
Passo 2
A Classe deve estar registrada
Exemplo:
initialization
RegisterClass(TExemploClasse);
Passo 3
Utilize esta função que criei para facilitar a vida
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | function ExecuteAwayMethod(ClassName, MethodName : string; MethosParams : array of TValue) : TValue; var ctx : TRttiContext; lType : TRttiType; lMethod : TRttiMethod; vClass : TClass; begin ctx := TRttiContext.Create; vClass := FindClass(ClassName); lType := ctx.GetType(vClass); Result := nil; try if Assigned(lType) then begin lMethod := lType.GetMethod(MethodName); if Assigned(lMethod) then Result := lMethod.Invoke(vClass, MethosParams); end; finally lMethod.Free; lType.Free; ctx.Free; end; end; |
Veja que aqui você informa o nome da classe, o nome do método e possíveis parâmetros do mesmo.
Inclusive é possível obter retorno de funções.
Para um melhor entendimento, abaixo tem o fonte na integra de exemplo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, rtti, Vcl.StdCtrls; type { Classe de exemplo, normalmente estará em outra unit } TExemploClasse = class(TPersistent) class function Teste(ANumber : Integer) : string; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; function ExecuteAwayMethod(ClassName, MethodName : string; MethosParams : array of TValue) : TValue; implementation {$R *.dfm} function ExecuteAwayMethod(ClassName, MethodName : string; MethosParams : array of TValue) : TValue; var ctx : TRttiContext; lType : TRttiType; lMethod : TRttiMethod; vClass : TClass; begin ctx := TRttiContext.Create; vClass := FindClass(ClassName); lType := ctx.GetType(vClass); Result := nil; try if Assigned(lType) then begin lMethod := lType.GetMethod(MethodName); if Assigned(lMethod) then Result := lMethod.Invoke(vClass, MethosParams); end; finally lMethod.Free; lType.Free; ctx.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); var vValue, vResult : TValue; begin vValue := 10; vResult := ExecuteAwayMethod('TExemploClasse', 'Teste', vValue) ; ShowMessage( vResult.AsString ); end; { TExemploClasse } class function TExemploClasse.Teste(ANumber: Integer): string; begin Result := ANumber.ToString; end; { Para uso deste exemplo, a classe precisa estar registrada } initialization RegisterClass(TExemploClasse); end. |
Dúvidas ou sugestões? deixe o seu comentário.
Fonte de referência: https://stackoverflow.com/questions/8102255/delphi-dynamically-calling-different-functions