我遇到了 "Delphi XE4 Indy compatibility issue between TBytes and TidBytes " 中提到的同样问题,即在使用 Delphi XE4 编译时,TBytes(Delphi RTL) 和 TIdBytes(Indy) 数据类型之间存在兼容性问题。我的问题源于代码不完全符合 Indy 的接口,并且一些函数在调用本地 Indy IO 过程时使用了 TBytes 而不是 TIdBytes。
所以我想知道最好的解决方法是什么?
我认为有两种方法:
所以我想知道最好的解决方法是什么?
我认为有两种方法:
- 重构项目中所有函数,改用 TIdBytes 而不是 TBytes。
- 实现一个 TBytesToTidBytes 转换过程(将 TBytes 转换为 TIdBytes),并在进行上述本地 Indy 调用之前调用该过程。
提醒:我正尝试通过XE4配置的项目可以在线上sourceforge找到: http://sourceforge.net/projects/indy10clieservr/?source=directory
建议的转换步骤应该类似于:
procedure TBytesToTIdBytes(const Input:TBytes, var Output: TIdBytes)
var
i,L : Integer;
allocate : Boolean;
begin
L := Length(Input);
if(Length(Output) <> L) then
begin
SetLength(Output,L);
end;
if(L > 0) then
move(Pointer(Input)^,Pointer(Output)^,L);
end;
allocate
变量没有任何作用,但是你的长度检查是危险的。如果数组具有相同的长度,则不会重新分配数组,但是如果目标数组的引用计数大于一,则最终会覆盖你可能不想要的数组。持有对数组的其他引用的代码可能会继续期望原始数据。更安全的做法是无条件地重新分配。 - Rob KennedySetLength
的时候,调用SetLength
没有实际效果。只有在allocate
为真时,才会因其值导致调用SetLength
。只有当Output
为空数组时,allocate
才为真,这意味着它是一个空数组。如果Input
是空数组,则不需要调用SetLength
,因为它只会使Output
变为空的,而我们已经知道它本来就是空的。如果Input
不为空,则长度比较将会评估为 true,即使没有检查allocate
的值,也将会导致调用SetLength
。 - Rob Kennedy