(Button3Click)
試行錯誤のうえで作成したソースなので、とりあえず動きましたが
正しいソースかどうかは、分かりません。もっと良い方法が
あれば教えて下さい。
この手の処理はActivatorクラスのある.Netのほうが簡単だと
思います。
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ExtCtrls,Unit2;
- type
- TForm2 = class(TForm)
- Button3: TButton;
- LabeledEdit1: TLabeledEdit;
- ListBox1: TListBox;
- Button1: TButton;
- Label1: TLabel;
- procedure Button3Click(Sender: TObject);
- procedure Button1Click(Sender: TObject);
- private
- { Private 宣言 }
- protected
- public
- { Public 宣言 }
- end;
- var
- Form1: TForm2;
- implementation
- uses
- Rtti,TypInfo;
- {$R *.dfm}
- procedure TForm2.Button1Click(Sender: TObject);
- var
- LContext: TRttiContext;
- LType: TRttiType;
- LTypes:TArray<trttitype>;
- begin
- LoadPackage('SakaPack.bpl');
- { Obtain the RTTI context }
- LContext := TRttiContext.Create;
- { Obtain the second package (rtl140) }
- LTypes := LContext.GetTypes();
- { Enumerate all types in the rtl140 package }
- //for LPackage in LPackages do
- //begin
- for LType in LTypes do
- begin
- ListBox1.Items.Add(LType.QualifiedName);
- end;
- //end;
- ListBox1.Items.SaveToFile('P.Txt');
- end;
- procedure TForm2.Button3Click(Sender: TObject);
- var
- ctx : TRttiContext;
- rtm : TRttiMethod;
- rst : TValue;
- SakaInf : ISakaTest;
- rtt : TRttiType;
- Args : Array of TValue;
- begin
- //とりあえず別パッケージで動的ロード化とする
- LoadPackage('SakaPack.bpl');
- ctx := TRttiContext.Create;
- //文字列で型情報を探す場合は、FindTypeを使う
- //完全一致なのでユニット名を含めて指定
- rtt := ctx.FindType('Unit2.' + LabeledEdit1.Text);
- //コンストラクタはとりあえずCreateであることが前提
- rtm := rtt.GetMethod('Create');
- if rtm <> nil then
- begin
- if rtm.IsConstructor then
- begin
- //1. クラスの場合は、TRttiInstanceTypeで戻ってくるのでキャスト
- //2. MetaaclassTypeプロパティで実際のクラスがとれるみたい。
- rst := rtm.Invoke(TRttiInstanceType(rtt).MetaclassType,Args);
- if rst.IsObject Then
- begin
- SakaInf := TSakaTest(rst.AsObject) As ISakaTest;
- Label1.Caption := SakaInf.SayMessage();
- end;
- //Label1.Caption := obj.ClassName;
- end;
- end;
- end;
- end.
- </trttitype>
でUnit2で使ったソースがこちら
- unit Unit2;
- interface
- uses classes;
- {$RTTI EXPLICIT METHODS([vcPublic])}
- Type ISakaTest = interface(IInterface)
- ['{FAAA20A5-E078-4E22-96C2-139E7E57CBFB}']
- function SayMessage : String;
- end;
- {$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
- Type TSakaTest = Class(TInterfacedPersistent, ISakaTest)
- function SayMessage : String; virtual;
- End;
- {$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
- Type TSakaTest1 = Class(TSakaTest)
- Public
- function SayMessage : String; override;
- End;
- {$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
- Type TSakaTest2 = Class(TSakaTest)
- Public
- function SayMessage : String; override;
- End;
- var
- SakaTest : ISakaTest;
- implementation
- //uses
- //Classes;
- { TSakaTest1 }
- function TSakaTest1.SayMessage: String;
- begin
- Result := 'Hello Delphi First';
- end;
- { TSakaTest2 }
- function TSakaTest2.SayMessage: String;
- begin
- Result := 'Hello Delphi Second';
- end;
- { TSakaTset }
- function TSakaTest.SayMessage: String;
- begin
- Result := '';
- end;
- initialization
- RegisterClass(TSakaTest);
- RegisterClass(TSakaTest1);
- RegisterClass(TSakaTest2);
- end.
0 件のコメント:
コメントを投稿