在tbytes和tidbytes之间的Delphi XE3 indy兼容性问题

时间:2013-10-16 11:37:08

标签: delphi bytearray indy delphi-xe3 indy10

我已经在Delphi XE4 Indy compatibility issue between TBytes and TidBytes发帖了 关于数据类型tbytes和tidbytes之间的兼容性问题。 从我学到的第二个答案来看,即使它们都是字节数组,它们看起来也不能一起使用。 然而,最新的答案说,在indy 10.5.9中,它依赖于TBytes的存在,并且仅在Indy 10.6中它完全作为字节数组提交。 无论如何,我有一个.pas单元,它解码来自IdUDPServerUDPRead事件的几个数据包,但无法将它们组合在一起。 我总是得到错误: [dcc32错误] Unit1.pas(216):E2250没有可以使用这些参数调用的'Unpack'的重载版本

但Unpack声明正确:

    class function Unpack(Bytes: TBytes; Count: Integer): TOSCPacket; overload;
class function Unpack(Bytes: TBytes; Offset, Count: Integer; TimeTag: Extended
    = 0): TOSCPacket; overload; virtual;

据我所知,我对它的使用也是如此:

OSCPacket.Unpack(AData, Length(Adata));

其中AData是字节数组。

我在这里做错了什么,我看不到? 我一直在谷歌搜索几个小时,并且找不到合并,转换,复制,移动或其他任何方式,从AData到实际可用变量的数据,以便将它放入Unpack函数的参数列表中。

任何帮助都不仅仅是值得赞赏的。

感谢,

榨渣

1 个答案:

答案 0 :(得分:4)

两个Unpack方法接收TBytes类型的参数。所以你需要传递那种类型的变量。您传递的array of Byte类型的变量与TBytes不兼容。

通过将变量声明为TBytes而不是array of Byte来解决问题。

Delphi中的类型兼容性有点混乱。就个人而言,我总是使用通用动态数组,它具有更多放松兼容性规则。因此,如果我控制所有涉及的代码,我会选择使用TArray<Byte>而不是TBytes

另一个选择是使用开放式数组,这是最灵活的参数。例如。

class function Unpack(const Bytes: array of Byte; Count: Integer): TOSCPacket;

该函数可以传递TBytesTIdBytesarray of ByteTArray<Byte>,开放数组构造函数,静态字节数组等变量。

请注意,您还应该将数组参数声明为const,以避免复制它们的开销。

更新1

很明显AData实际上是一个开放数组而不是动态数组。在这种情况下,您应该使您的函数接收开放数组。

我认为您的代码是在TUDPReadEvent类型的方法中执行的:

type
  TUDPReadEvent = procedure(AThread: TIdUDPListenerThread; AData: array of Byte; 
    ABinding: TIdSocketHandle) of object;

在这种情况下TIdBytes不相关,这里没有任何类型。 AData不是动态数组,而是一个开放数组参数。因此,您还需要声明函数以使用开放数组。

顺便说一句,我觉得印第安人在TUDPReadEvent的宣言中搞砸了。 AData参数确实应该作为const传递。请参阅Remy的评论:这是Emba搞砸了。

您应该阅读documentation of open array parameters以确保您完全理解开放数组参数和动态数组之间的区别。

更新2

如果您无法修改这些接口中的任何一个,则必须在它们之间放置一个适配器。例如:

function CopyBytes(const Bytes: array of Byte): TBytes;
var
  Count: Integer;
begin
  Count := Length(Bytes);
  SetLength(Result, Count);
  if Count > 0 then
    Move(Bytes[0], Result[0], Length(Bytes));
end;