我已经在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”重载版本

但是解压缩已正确声明:

    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函数的参数列表中。

任何帮助将不胜感激。

谢谢,

马克

最佳答案

这两个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传递。参见雷米的评论:是Emba搞砸了。

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

更新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;

07-24 20:21