我定义了这个打包记录:
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 的数组,由所有需要的数据组成(已排序)。
我怎么能在循环中填充结构/甚至有办法吗?
答案 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)