TArray <byte> VS TBytes VS PByteArray </byte>

时间:2010-03-11 18:15:37

标签: delphi delphi-2010

这三种类型非常相似......

TArray是TBytes的通用版本。 两者都可以转换为PByteArray并用作调用Windows API的缓冲区。 (与字符串到Pchar的限制相同)。

我想知道的是:这种行为是“按设计”还是“按实施”。或者更具体地说,它可能会在未来的版本中破裂吗?

//编辑 如下所述...... 我真正想知道的是:将TBytes(或TArray)类型化为PByteArray是安全的,因为就前向兼容性而言,将字符串转换为PChar。 (或者也许AnsiString到PAnsiChar是一个更好的例子^ _ ^)

2 个答案:

答案 0 :(得分:3)

简单地说,字节数组是一个字节数组,只要字节和数组的定义不变,这也不会改变。你可以安全地使用它,只要你确保尊重数组边界,因为从Delphi的数组类型中抛出它会使你的边界检查无效。

编辑:我想我现在看到你要求的更好了。

不,您不应该将动态数组引用强制转换为C样式的数组指针。您可以使用字符串来逃避它,因为编译器可以帮助您解决一些问题。

但是,您可以执行的操作是将指向动态数组的元素0的指针转换为C样式的数组指针。 工作,不会改变。

答案 1 :(得分:1)

其中两种类型相似(实际上相同)。第三个不是。

TArray 被声明为“字节数组”, TBytes 也是如此。您错过了另一个非常相关的类型, TByteArray PByteArray 引用的类型)。

作为指向 TByteArray 的指针, PByteArray 严格来说是一个指向静态字节数组的指针,而不是动态数组(其他字节数组都是类型)。它以这种方式键入,以允许使用整数索引引用来自该基址指针的偏移量。请注意,此索引限制为2 ^ 15个元素(0..32767)。对于来自某个基指针的任意字节偏移(> 32767), PByteArray 是不好的:

var
  b: Byte;
  ab: TArray<Byte>;
  pba: PByteArray;
begin
  SetLength(ab, 100000);
  pba := @ab;             // << No cast necessary - the compiler knows (magic!)
  b   := pba[62767];      // << COMPILE ERROR!
end;

即。将字节阵列 TArray 投射到 PByteArray 可能会导致阵列出现问题&gt; 32K元素(并将指针传递给一些试图访问所有元素的代码)。转换为无类型指针当然可以避免这种情况(只要指针的“接收者”适当地处理指针对内存引用的访问)。

但是,这一切都不会在将来发生变化,这仅仅是长期以来在这一领域应用的实施细节的结果。语法加糖泛型类型声明的引入是 kipper rouge