2

我已经在Delphi XE4 Indy compatibility issue between TBytes and TidBytes 看到 了关于数据类型 tbytes 和 tidbytes 之间的兼容性问题的帖子。从我了解到的第二个答案中,即使它们都是字节数组,它们看起来也不能一起使用。但是,最新的答案说,在 indy 10.5.9 中它取决于 TBytes 的存在,并且只有在 Indy 10.6 中它才完全作为字节数组提交。无论如何,我有一个 .pas 单元,它可以解码来自 IdUDPServerUDPRead 事件的几个数据包,但不能将它们放在一起。我总是收到错误:[dcc32 Error] 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 函数的参数列表中。

任何帮助将不胜感激。

谢谢,

马克

4

1 回答 1

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实际上是一个开放数组而不是动态数组。在这种情况下,您应该让您的函数接收开放数组。

我认为您的代码在 type 的方法中执行TUDPReadEvent

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

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

顺便说一句,在我看来,印地人在声明中搞砸了TUDPReadEvent。该AData参数确实应该作为const. 请参阅 Remy 的评论:是 Emba 搞砸了这一切。

您应该阅读开放数组参数的文档,以确保您完全理解开放数组参数和动态数组之间的区别。

更新 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;
于 2013-10-16T11:40:28.337 回答