我为Byte集合定义了一个类型,一个接口和一个实现该接口的类。 该接口具有 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。
谢谢!
答案 0 :(得分:3)
当TRttiType.GetValue()
(更具体地说,Invoke()
单元中的System.Rtti
函数)尝试调用TTestClass3.GetPropSetOfByte()
时,它会崩溃。正在传入正确的Self
指针,但Result
参数为nil,因此当GetPropSetOfByte()
尝试将FSetOfByte
分配给Result
时会发生崩溃。< / p>
简而言之,RTTI系统没有为基于Set
的属性正确设置调用堆栈。我已经在XE2,XE6和XE7中复制了崩溃,并向Embarcadero提交了一份错误报告:
TRttiProperty.GetValue()在基于Set的属性上崩溃 https://quality.embarcadero.com/browse/RSP-10206