저는 최근에 인터페이스와 D2010 RTTI를 광범위하게 실험했습니다. 런타임시 인터페이스의 실제 유형을 알지 못합니다. 문자열을 사용하는 정규화 된 이름에 액세스 할 수는 있지만 다음 mynamespace.pas
의TValue를 사용하여 델파이 인터페이스 캐스트
program rtti_sb_1;
{$APPTYPE CONSOLE}
uses
SysUtils, Rtti, TypInfo, mynamespace in 'mynamespace.pas';
var
ctx: TRttiContext;
InterfaceType: TRttiType;
Method: TRttiMethod;
ActualParentInstance: IParent;
ChildInterfaceValue: TValue;
ParentInterfaceValue: TValue;
begin
ctx := TRttiContext.Create;
// Instantiation
ActualParentInstance := TChild.Create as IParent;
{$define WORKAROUND}
{$ifdef WORKAROUND}
InterfaceType := ctx.GetType(TypeInfo(IParent));
InterfaceType := ctx.GetType(TypeInfo(IChild));
{$endif}
// Fetch interface type
InterfaceType := ctx.FindType('mynamespace.IParent');
// This cast is OK and ChildMethod is executed
(ActualParentInstance as IChild).ChildMethod(100);
// Create a TValue holding the interface
TValue.Make(@ActualParentInstance, InterfaceType.Handle, ParentInterfaceValue);
InterfaceType := ctx.FindType('mynamespace.IChild');
// This cast doesn't work
if ParentInterfaceValue.TryCast(InterfaceType.Handle, ChildInterfaceValue) then begin
Method := InterfaceType.GetMethod('ChildMethod');
if (Method <> nil) then begin
Method.Invoke(ChildInterfaceValue, [100]);
end;
end;
ReadLn;
end.
내용된다 :
다음을 고려해야
procedure TParent.ParentMethod(const Id: integer);
begin
WriteLn('ParentMethod executed. Id is ' + IntToStr(Id));
end;
procedure TChild.ChildMethod(const Id: integer);
begin
WriteLn('ChildMethod executed. Id is ' + IntToStr(Id));
end;
가 {$define WORKAROUND}
이유가있을 수 있으므로
{$M+}
IParent = interface
['{2375F59E-D432-4D7D-8D62-768F4225FFD1}']
procedure ParentMethod(const Id: integer);
end;
{$M-}
IChild = interface(IParent)
['{6F89487E-5BB7-42FC-A760-38DA2329E0C5}']
procedure ChildMethod(const Id: integer);
end;
TParent = class(TInterfacedObject, IParent)
public
procedure ParentMethod(const Id: integer);
end;
TChild = class(TParent, IChild)
public
procedure ChildMethod(const Id: integer);
end;
, 구현 간다 발견 된 in this post.
질문 : RTTI를 사용하여 원하는 유형의 캐스트를 만들 수있는 방법이 있습니까? 즉, IChild.ChildMethod를 호출하여 IChild의 정규화 된 이름을 문자열로, 2) Tarent 인스턴스를 IParent 인터페이스로 참조하는 것을 알 수있는 방법이 있습니까? (결국, 하드 코딩 된 캐스트가 잘 작동합니다.이게 가능합니까?) 감사합니다!
남자, 그렇게 많은 의미가 있습니다! 왜 이것이 작동하지 않는지 나는 정말로 이해할 수 없었다. 다시 한 번 구조하십시오! :) (+1) 아침에 QC에보고하겠습니다. – conciliator
오전이 예상보다 빨리 나타났습니다. 이제 QC# 85339에서 신고되었습니다. – conciliator