【发布时间】:2013-09-21 20:16:18
【问题描述】:
我遇到了与“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变量没有任何作用,但您的长度检查很危险。如果数组具有相同的长度,那么您将不会重新分配数组,但如果目标数组的引用计数大于 1,您最终将覆盖您可能不打算这样做的数组。保存对数组的其他引用的代码可能会继续期待原始数据。无条件重新分配更安全。 -
我明白你的意思。但是,为什么您认为 allocate 变量是无用的?它旨在指示目标数组之前是否已分配。
-
它没用,因为它真正影响您是否调用
SetLength的唯一时间,对SetLength的调用没有净效果。allocate的值唯一让你调用SetLength的时候是它为真。allocate为真的唯一方法是当Output为空时,这意味着它是一个空数组。如果Input是一个空数组,那么您不需要调用SetLength,因为它只会使Output为空,我们知道它已经是空的。如果Input不为空,那么即使不检查allocate的值,长度比较也会评估为真无论如何。 -
注意到了!但是,由于我正在处理大量数据,我想更简单的类型转换解决方案更可取。谢谢。
-
作为与不兼容类型作战的替代方法,您可以声明您的函数以接收开放数组中的数据。