从 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
我为一组字节定义了一个类型,一个接口和一个实现该接口的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