【发布时间】:2017-01-04 12:43:07
【问题描述】:
如何将TArray<Byte> 分配给array of Byte,反之亦然?
TEncoding.UTF8.GetBytes 返回一个TArray<Byte>。 TIdHashMessageDigest5.HashBytes 有一个 TIdBytes = array of Byte 作为参数。
我可以将这些类型分配给彼此吗?也许有副本?还是我需要循环?
【问题讨论】:
如何将TArray<Byte> 分配给array of Byte,反之亦然?
TEncoding.UTF8.GetBytes 返回一个TArray<Byte>。 TIdHashMessageDigest5.HashBytes 有一个 TIdBytes = array of Byte 作为参数。
我可以将这些类型分配给彼此吗?也许有副本?还是我需要循环?
【问题讨论】:
这些类型不兼容赋值。在理想的世界中,您将专门使用TArray<T>,如果所有库都这样做会更好。我不明白为什么 Indy 坚持在这里使用自己独特的类型。
如果你不能,那么你可以制作一个副本。使用循环很容易。如果效率很重要,您可以使用Move 进行复制。
SetLength(Dest, Length(Source));
Move(Pointer(Source)^, Pointer(Dest)^, Length(Source));
我在这里使用Pointer(arr)^ 而不是arr[0] 以避免在空数组的情况下触发范围检查异常。
也可以通过使用类型转换来避免复制,因为所有动态数组都以相同的方式实现。所以你可以写
Hash := HashBytes(TIdBytes(TEncoding.UTF8.GetBytes(...)));
当然,这放弃了类型安全,但是上面对Move 的调用也是如此。
Remy's answer to another question 建议的另一种方法是使用TIdTextEncoding 而不是TEncoding。这样您就可以专门使用TIdBytes。
【讨论】:
TIdBytes 可以很容易地有条件地定义来解决这个问题。
TIdBytes 在可用时曾是 TBytes 的别名(可用时是 TArray<Byte> 的别名),但这样做会导致很多问题,尤其是在跨越 Delphi/C++ 边界的多个事件处理程序(Embarcadero RTTI 错误)。所以最终我别无选择,只能让TIdBytes 回到使用array of Byte 来维持正常的功能。这不是为了处理向后兼容性,而是为了处理 Embarcadero 错误。