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 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功能。看起来很漂亮!

关于delphi - rtti的遍历记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5202489/

10-11 23:07