通过索引迭代记录

时间:2017-01-27 00:18:14

标签: delphi record

我定义了这个打包记录:

  TReplayData = packed record
    GameMode : Byte;
    VersionReplayCreation : Integer;
    BeatMapMD5Hash : String;
    PlayerName : String;
    NumberOf300s : Short;
    NumberOf100s : Short;
    NumberOf50s : Short;
    NumberOfGekis : Short;
    NumberOfKatus : Short;
    NumberOfMisses : Short;
    TotalScore : Integer;
    GreatestCombo : Short;
    Perfect : Byte;
    ModsUsed : Integer;
    LifeBarGraph : String;
    TimeStamp : Long;
    LengthInBytes : Integer;
    ReplayData : TByteArray;
    Unknown : Long;
  end;

我想填写它(伪代码 /不工作):

  for i := 0 to SizeOf(TReplayData) - 1 do
  begin
    CopyMemory(ReplayData[i], AReplayBuffer + SizeOf(ReplayData[i]), SizeOf(ReplayData[i]));
  end;

这显然不起作用。 AReplayBuffer 是Char 的数组,由所有需要的数据组成(已排序)。

我怎么能在循环中填充结构/甚至有办法吗?

1 个答案:

答案 0 :(得分:0)

第一个问题

FreePascal文档:http://wiki.freepascal.org/Character_and_string_types#ShortString表明String类型可能引用ShortString或AnsiString,具体取决于编译器设置({$ H}开关)。

同一页面也说"在内部,AnsiString类型的变量被视为指针:字符串的实际内容存储在堆"上。因此,如果是这种情况,则通过指针变量写入二进制数据将导致指针无效。

解决方案:确保使用ShortString(对于MD5和播放器名称,大小限制应该不是问题)。

第二个问题

您尝试将内存从ReplayData成员复制到包含 ReplayData的整个记录​​。即使您尝试从TReplayData的两个不同实例进行复制,也不会有足够的空间。因此SizeOf(TReplayData)将大于SizeOf(ReplayData)

解决方案:将ReplayData: TByteArray放在记录之外。 (N.B. TByteArray定义为32767字节长,导致浪费空间,请参阅http://www.freepascal.org/docs-html/rtl/sysutils/tbytearray.html