RTTI and Delphi 2010 Fields

I have a problem with properties like IInterface. I do not know how to assign values ​​to these properties using RTTI

Here is an example:

program Project2; uses Forms, RTTI, Windows, TypInfo; {$R *.res} type ITestInterfacedClass = interface ['{25A5B554-667E-4FE4-B932-A5B8D9052A17}'] function GetA: ITestInterfacedClass; procedure SetA(const Value: ITestInterfacedClass); property A: ITestInterfacedClass read GetA write SetA; function GetB: ITestInterfacedClass; procedure SetB(const Value: ITestInterfacedClass); property B: ITestInterfacedClass read GetB write SetB; end; TTestInterfacedClass = class(TInterfacedObject, ITestInterfacedClass) private FA: ITestInterfacedClass; FB: ITestInterfacedClass; function GetA: ITestInterfacedClass; function GetB: ITestInterfacedClass; procedure SetA(const Value: ITestInterfacedClass); procedure SetB(const Value: ITestInterfacedClass); public property A: ITestInterfacedClass read GetA write SetA; property B: ITestInterfacedClass read GetB write SetB; end; { ITestInterfacedClass } .... procedure SetProperty(aLeft: TObject {IInterface}; aNameProp: string; aRight: IInterface); var RttiContext: TRttiContext; RttiType: TRttiType; RTTIProperty: TRttiProperty; begin RttiContext := TRttiContext.Create; RTTIType := RttiContext.GetType(TTestInterfacedClass); RTTIProperty := RTTIType.GetProperty(aNameProp); if RTTIProperty.PropertyType.TypeKind = tkInterface then RTTIProperty.SetValue(aLeft, TValue.From<IInterface>(aRight)); end; var obj1: TTestInterfacedClass; intf1, intf2, intf3: ITestInterfacedClass; begin obj1 := TTestInterfacedClass.Create; intf1 := obj1; intf2 := TTestInterfacedClass.Create; intf3 := TTestInterfacedClass.Create; intf1.A := intf2; // intf1.B := intf3; SetProperty(obj1, 'B', intf3); end. 

I need to write an analog intf1.B: = intf3; or obj1.B = intf3;

using RTTI.

Is it possible?

UPD This is the job:

 procedure SetProperty(aLeft: TObject; aNameProp: string; aRight: IInterface); var RttiContext: TRttiContext; RttiTypeInterface: TRttiInterfaceType; RTTIProperty: TRttiProperty; Value: TValue; begin RttiContext := TRttiContext.Create; RTTIType := RttiContext.GetType(aLeft.ClassType); RTTIProperty := RTTIType.GetProperty(aNameProp); if RTTIProperty.PropertyType.TypeKind = tkInterface then begin TValue.Make(@aRight, RTTIProperty.PropertyType.Handle, Value); RTTIProperty.SetValue(aLeft, Value); end; end; 
+6
rtti delphi
source share
1 answer

Unfortunately, this does not work, because the interface conversion code in RTTI.pas does not call QueryInterface. If you insert TValue using TValue.From<IInterface> , you cannot convert it to TValue of another type of interface, even if the interface supports this type. Feel free to submit this to QC.

Creating a TValue using TValue.From<ITestInterfacedClass> really works. But then you cannot use the simple SetProperty procedure.

+2
source share

All Articles