【问题标题】:delphi2010 Traversal record of rttidelphi2010 rtti的遍历记录
【发布时间】:2011-03-05 07:54:17
【问题描述】:
type
 myrec = record
 id:dWord;
 name:array[0..31] of  WideChar;
 three:dword;
 count:dword;
 ShuXing:Single;
 ShuXing2:dword;
 ShuXing3:dWORD;

  end;

var
  Form1: TForm1;
  mystr:TMemoryStream;
  nowmyrec:myrec;

implementation
 USES Rtti;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);


var
  rttiContext: TRttiContext;
  rttiType: TRttiType;
  fields: TArray<TRttiField>;
  item: myrec;
  i:word;
begin
mystr:=TMemoryStream.Create;
mystr.LoadFromFile(ExtractFilePath(Application.exename)+'1.data');
mystr.Position:=20;
mystr.readbuffer(nowmyRec,88);




 rttiType := rttiContext.GetType(TypeInfo(myRec));
  fields := rttiType.GetFields;
   for i := low(fields) to high(fields) do
   begin
Memo1.Lines.Add(fields[i].GetValue(@nowmyRec).ToString );


   end;

end;

end.

myrec.name 是汉字,myrec.name 的长度是 64 字节,我无法读取 myrec.name 到备忘录,请帮帮我!!!

【问题讨论】:

    标签: delphi rtti


    【解决方案1】:

    我使用的是 Delphi 2010,我发现您的代码存在一些问题。首先,我无法让 RTTI 方法与字符数组的内联声明一起工作。我把它改成:

    type
      TCharArray = array[0..31] of WideChar;
      TRec = record
        id:dWord;
        name:TCharArray;
      end;
    

    如果您声明数组内联,按​​照您所做的方式,对GetValue 的调用会引发 AV。这可能在 XE 中已修复,或者很可能我使用的 RTTI 不正确。

    其次,您需要对数组进行特殊处理,而不是标量值:

    procedure Main;
    var
      i, j: Integer;
      rec: TRec;
      rttiContext: TRttiContext;
      rttiType: TRttiType;
      fields: TArray<TRttiField>;
      val: TValue;
      s: string;
    begin
      rec.id := 1;
      rec.name := 'Hello Stack Overflow';
    
      rttiType := rttiContext.GetType(TypeInfo(TRec));
      fields := rttiType.GetFields;
      for i := low(fields) to high(fields) do begin
        val := fields[i].GetValue(@rec);
        if val.IsArray then begin
          s := '';
          for j := 0 to val.GetArrayLength-1 do begin
            s := s+val.GetArrayElement(j).ToString;
          end;
          Writeln(s);
        end else begin
          Writeln(val.ToString);
        end;
      end;
    end;
    

    输出:

    1
    Hello Stack Overflow
    

    这显然不是生产代码,但它至少应该让你重新上路!

    附:这是我第一次看到新的 RTTI 功能。它看起来很漂亮!

    【讨论】:

    • 我正在读取十六进制数据,它必须使用 tstream ! " rec.name := 'Hello Stack Overflow': 不适合我
    • @baba 您的问题在于 RTTI 而不是流代码。由于我手头没有您的二进制输入数据,因此我用自己的数据填充了记录,只是为了证明 RTTI 代码有效。随意填充您自己的记录。
    • @baba 为什么不按照我的建议更改记录的定义。这将在第二次调用 GetValue 时停止 AV。然后用我添加了IsArray 的版本替换调用fields[i].GetValue(@nowmyRec).ToString 的代码。然后它会工作。
    • @baba 感谢您的接受。我相信你现在很满足。顺便说一句,你现在有足够的声望投票!! ;-)
    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2021-10-13
    相关资源
    最近更新 更多