我已经在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;
该函数可以传递
TBytes
,TIdBytes
,array of Byte
,TArray<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;