我已经在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函数的参数列表中。
任何帮助都不仅仅是值得赞赏的。
感谢,
榨渣
答案 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;
该函数可以传递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
不是动态数组,而是一个开放数组参数。因此,您还需要声明函数以使用开放数组。
顺便说一句,我觉得印第安人在请参阅Remy的评论:这是Emba搞砸了。TUDPReadEvent
的宣言中搞砸了。 AData
参数确实应该作为const
传递。
您应该阅读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;