为什么TRttiField.GetValue无法填充结果?

时间:2016-02-08 01:25:37

标签: delphi data-structures rtti

我有一个非常复杂的嵌套记录类型。我需要在方法调用后监视它的字段值的变化。我使用RTTI来做(最初从here复制):

procedure CompareFields(const Rec1, Rec2: Pointer; const RectTypeInfo: TRttiType;
  const BaseName: string; const BaseOffset: Integer; const Lines: TStrings);
var
  R1Field, R2Field: Pointer;
  MyField: TRttiField;
  State: string;
  Path: string;
begin
  if RectTypeInfo.TypeKind = tkRecord then
  begin
    for MyField in RectTypeInfo.GetFields do
    begin
      R1Field := Pointer(Integer(Rec1) + BaseOffset + MyField.Offset);
      R2Field := Pointer(Integer(Rec2) + BaseOffset + MyField.Offset);
      if CompareMem(R1Field, R2Field, MyField.FieldType.TypeSize) then
        State := '=='
       else
         State :=  '<>';
      Path := BaseName + '.' + MyField.Name;

      Lines.Add(Format('%2s | %-20s | +%2d | %10s[%2d] | %22s | %22s', [State, Path,
        BaseOffset + MyField.Offset,
        MyField.FieldType.ToString,
        MyField.FieldType.TypeSize,
        MyField.GetValue(R1Field).ToString,
        MyField.GetValue(R2Field).ToString]));

      if MyField.FieldType.TypeKind = tkRecord then
        CompareFields(Rec1, Rec2, MyField.FieldType, Path, BaseOffset + MyField.Offset, Lines);
    end;
  end;
end;

CompareMem部分工作正常并清楚地表明已更改的字段。但问题在于报告拖曳记录的价值。 MyField.GetValue(R1Field).ToString有时会返回一个随机值,因为MyField.GetValue(R1Field)会使用随机值填充结果。 这是一个演示问题的示例:

type
  TMyRec1 = record
    F11: Integer;
    F12: Boolean;
    F13: Double;
  end;

  TMyRec2 = record
    F21, F22: TMyRec1;
    F23: Integer;
    F24: TMyRec1;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyContext: TRttiContext;
  Rec1, Rec2: TMyRec2;
begin
  FillChar(Rec1, SizeOf(Rec1), #0);
  FillChar(Rec2, SizeOf(Rec1), #0);

  CompareFields(@Rec1, @Rec2, MyContext.GetType(TypeInfo(TMyRec2)), 'TMyRec2', 0,
    Memo1.Lines);

end;

结果是:

== | TMyRec2.F21          | + 0 |    TMyRec1[16] |               (record) |               (record)
== | TMyRec2.F21.F11      | + 0 |    Integer[ 4] |                      0 |                      0
== | TMyRec2.F21.F12      | + 4 |    Boolean[ 1] |                  False |                  False
== | TMyRec2.F21.F13      | + 8 |     Double[ 8] |                      0 |                      0
== | TMyRec2.F22          | +16 |    TMyRec1[16] |               (record) |               (record)
== | TMyRec2.F22.F11      | +16 |    Integer[ 4] |                      0 |                      0
== | TMyRec2.F22.F12      | +20 |    Boolean[ 1] |                  False |                  False
== | TMyRec2.F22.F13      | +24 |     Double[ 8] |                      0 |                      0
== | TMyRec2.F23          | +32 |    Integer[ 4] |               21013568 |                      0 <<--
== | TMyRec2.F24          | +40 |    TMyRec1[16] |               (record) |               (record)
== | TMyRec2.F24.F11      | +40 |    Integer[ 4] |                      0 |                      0
== | TMyRec2.F24.F12      | +44 |    Boolean[ 1] |                  False |                  False
== | TMyRec2.F24.F13      | +48 |     Double[ 8] |  9.92338439963001E-303 |                      0 <<--

正如您所看到的,TMyRec2.F23TMyRec2.F24.F13似乎的值不是&#39; 0&#39;甚至在致电FillChar之后!

0 个答案:

没有答案