我应该如何调整我的代码以实现TBytes和TIdBytes之间的兼容性?

时间:2013-09-17 11:47:50

标签: delphi indy10

我遇到与“Delphi XE4 Indy compatibility issue between TBytes and TidBytes”中提到的问题相同的问题,即在使用Delphi XE4进行编译时TBytes(Delphi RTL)和TIdBytes(Indy)数据类型之间的兼容性问题。我的问题的根源是代码不完全符合Indy的接口,并且一些函数在调用本机Indy IO过程时使用TBytes而不是TIdBytes。

所以我想知道最好的解决方案是什么?

我认为有两种方法:

  1. 重构项目中的所有函数以使用TIdBytes而不是TBytes。

  2. 实施TBytesToTidBytes转换程序(将TBytes转换为TIdBytes)并在进行上述本地Indy调用之前调用该程序。

  3. 哪种方法更好/最好?你对我如何做到这一点还有其他想法吗?

    仅供参考:我尝试使用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;
    

2 个答案:

答案 0 :(得分:5)

TBytesTIdBytes都是作为动态数组实现的,它们只是以不同方式声明。 “政治上正确”的解决方案是制作字节的副本。但这会浪费大型阵列的内存。更简单的解决方案是使用类型转换,以便您可以利用数组的内部引用计数,例如:

type
  PIdBytes = ^TIdBytes;
var
  B1: TBytes;
  B2: TIdBytes;
begin
  B1 := ...;
  B2 := PIdBytes(@B1)^;
end;

或者简单地说:

var
  B1: TBytes;
  B2: TIdBytes;
begin
  B1 := ...;
  B2 := TIdBytes(B1);
end;

答案 1 :(得分:1)

两种类型在实现级别上都不一样,在较新的Delphi版本中(TBytes在最近的Delphi版本中是TArray<Byte>的简单别名)。

所以我想你可以使用这样的程序:

procedure TBytesToTIdBytes(const Input: TBytes; var Output: TIdBytes);
var L: integer;
begin
  L := Length(Input);
  SetLength(Output,L);
  move(Input[0],Output[0],L);
end;

此处move()比循环更快。