【问题标题】:Correct way to copy data from TBytes to Array of Byte in Delphi在Delphi中将数据从TBytes复制到字节数组的正确方法
【发布时间】:2015-09-03 12:51:49
【问题描述】:

鉴于以下情况:

LBytes: TBytes;
LArr: array[1..512] of Byte;
...
SetLength(LBytes, 512);

将所有字节从 LBytes 复制到 LArr 的正确 Move() 调用是什么?

Move(LBytes[0], LArr, Length(LBytes)); // works

Move(LBytes[0], LArr[1], Length(LBytes)); // works, too

Move(LBytes, LArr[1], Length(LBytes)); // fail

有人能解释一下为什么使用 Larr 和 Larr[1] 没有区别,但在 LBytes[0] 和 LBytes 之间有区别吗?

【问题讨论】:

  • LBytes -> 指向 TBytes 的指针,LBytes[ 0 ] 指向第一个元素。 LArr 是一个固定大小的数组,因此 LArr 和 LArr[1] 相同(例如指向第一个元素)。因此前两个是正确的。使用您认为最易读的任何内容。

标签: delphi pascal


【解决方案1】:

有人能解释一下为什么使用 Larr 和 Larr1 没有区别,但在 LBytes[0] 和 LBytes 之间有区别吗?

这是因为LBytes 是一个动态数组,它最终是一个指向数组的指针。另一方面,LArr 是数组。

另一种说法是动态数组是引用类型,而定长数组是值类型。

在我的书中,有两种可行的方法来做到这一点:

Assert(Length(LBytes)<=Length(LArr));
Move(LBytes[0], LArr, Length(LBytes));

Assert(Length(LBytes)<=Length(LArr));
Move(Pointer(LBytes)^, LArr, Length(LBytes));

我更喜欢后者,因为当启用范围检查时,它可以适应零长度数组。在这种情况下,第一个代码块会导致运行时范围检查错误。

您也可能有动力避免这种低级的诡计。我有一个utility class 允许我写:

TArray.Move<Byte>(LBytes, LArr);

方法的签名是:

class procedure Move<T>(const Source: array of T; var Dest: array of T); overload; static;

【讨论】:

  • 我喜欢实用程序类 Move。有这个单位吗?
猜你喜欢
  • 2011-11-21
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多