在Delphi中将数据从TBytes复制到Byte数组的正确方法

cyt*_*nox 6 delphi pascal

鉴于以下内容:

LBytes: TBytes;
LArr: array[1..512] of Byte;
...
SetLength(LBytes, 512);
Run Code Online (Sandbox Code Playgroud)

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

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

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

Move(LBytes, LArr[1], Length(LBytes)); // fail
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么使用Larr和Larr [1]没有区别但LBytes [0]和LBytes之间有区别吗?

Dav*_*nan 9

有人可以解释为什么使用Larr和Larr 1没有区别但LBytes [0]和LBytes之间有区别吗?

那是因为它LBytes是一个动态数组,最终是指向数组的指针.另一方面,LArr是阵列.

另一种说法是动态数组是引用类型,固定长度数组是值类型.

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

Assert(Length(LBytes)<=Length(LArr));
Move(LBytes[0], LArr, Length(LBytes));
Run Code Online (Sandbox Code Playgroud)

要么

Assert(Length(LBytes)<=Length(LArr));
Move(Pointer(LBytes)^, LArr, Length(LBytes));
Run Code Online (Sandbox Code Playgroud)

我更喜欢后者,因为在启用范围检查时,它对零长度数组具有弹性.在这种情况下,第一个代码块会导致运行时范围检查错误.

你也可能有动力去避免这种低级别的诡计.我有一个实用程序类,允许我写:

TArray.Move<Byte>(LBytes, LArr);
Run Code Online (Sandbox Code Playgroud)

该方法的签名是:

class procedure Move<T>(const Source: array of T; var Dest: array of T); overload; static;
Run Code Online (Sandbox Code Playgroud)