从 TRtti属性 读取 TValue 失败(属性 类型:字节集)

Reading TValue from TRttiProperty fails (Property Type: set of Byte)

我为一组字节定义了一个类型,一个接口和一个实现该接口的class。 该接口有一个类型为 TTestSetofByte + getter 和 setter 的 属性。没什么特别的。

type
 TTestSetOfByte = set of Byte;
  ITestInterface = interface
    ['{BCF0CEC2-F999-4E8A-A732-416F343C1629}']
    function GetPropSetOfByte: TTestSetOfByte;
    procedure SetPropSetOfByte(const Value: TTestSetOfByte);
    property PropSetOfByte: TTestSetOfByte read GetPropSetOfByte write SetPropSetOfByte;
  end;

  TTestClass3 = class(TInterfacedObject, ITestInterface)
  private
    FSetOfByte: TTestSetOfByte;
    function GetPropSetOfByte: TTestSetOfByte;
    procedure SetPropSetOfByte(const Value: TTestSetOfByte);
  public
    constructor Create;
    property PropSetOfByte: TTestSetOfByte read GetPropSetOfByte write SetPropSetOfByte;
  end;

问题是当我尝试读取 PropSetOfByte 属性 delphi 的值时抛出 EAccessViolation 我不明白为什么。其他类型的属性(int、string)工作得很好。

这里是测试代码:

procedure TTestUtlRttiComparer.DeleteMe;
var
  i: Integer;
  Instance1: ITestInterface;
  Object1: TObject;
  RttiContext: TRttiContext;
  RttiProp: TRttiProperty;
  RttiValue1: TValue;
  Type1: TRttiType;
begin
  Instance1 := TTestClass3.Create;
  Check(Instance1.PropSetOfByte = [1,4], 'Making sure getter works!');
  Instance1.PropSetOfByte := [3,4];
  Check(Instance1.PropSetOfByte = [3,4], 'Making sure setter works!');

  Object1 := (Instance1 as TObject);
  Check(Assigned(Object1));

  RttiContext := TRttiContext.Create;
  try
    Type1 := RttiContext.GetType(Object1.ClassInfo);

    // Properties pruefen
    for i := 0 to High(Type1.GetProperties) do
    begin
      RttiProp :=  Type1.GetProperties[i];
      if RttiProp.Name = 'PropSetOfByte' then
      begin
        RttiValue1 := RttiProp.GetValue(Object1); // THIS CHECK FAILS with EACESSVIOLATION!!!
      end;
    end;
  finally
    RttiContext.Free;
  end;
end;

我正在使用 XE-2。

谢谢!

它在 TRttiType.GetValue()(更具体地说,System.Rtti 单元中的 Invoke() 函数)尝试调用 TTestClass3.GetPropSetOfByte() 时崩溃。正在传入正确的 Self 指针,但 Result 参数为 nil,因此当 GetPropSetOfByte() 尝试将 FSetOfByte 分配给 Result 时发生崩溃。

简而言之,RTTI 系统没有为基于 Set 的属性正确设置调用堆栈。我在 XE2、XE6 和 XE7 中重现了崩溃,并向 Embarcadero 提交了错误报告:

TRttiProperty.GetValue() 在基于集合的 属性 上崩溃 https://quality.embarcadero.com/browse/RSP-10206