如何将动态数组的长度更改为“out”参数?

时间:2009-07-23 14:27:21

标签: delphi

我写了一个函数,它将一个物理包中收到的两个或多个数据包分开。但是,编译器并不欣赏我的努力。 每个数据包的大小都在数据包标头的前两个字节中,即6个字节。所以一个真正的数据包=它的前两个字节+ 6.这就是我发现是否有多个数据包。

procedure SeparatePackets(packet:pointer;size:word; out Result:Array of pointer; out number:byte);
var position:byte; //position
begin
  position:= 0;
  number:= 0;
  SetLength(Result,0); //<< ERROR

  while(PWord(Cardinal(packet) + position)^ + 6 <> size) do  //while the first two bytes + 6(packet header)
  begin
    SetLength(Result,Length(Result) + 1); //inc the length << ERROR
    Result[number] := Cardinal(packet) + position;
    position := Result[number] + PWord(Cardinal(packet) + position)^ + 6;
    inc(number);
  end;
end;

我用'&lt;&lt;标记了编译时错误错误'。错误是一个 - '不兼容的类型'。

我从来不知道在一个物理数据包中可能收到的数据包数量,因此如果数量增加,我想增加数组的长度。

如何解决我的错误?

5 个答案:

答案 0 :(得分:5)

如何创建新类型?我认为它应该有用。

type
  TPntArray = array of Pointer;

答案 1 :(得分:5)

声明一个新类型:

type
  TPointerDynArray = array of Pointer;

procedure SeparatePackets(Packet: Pointer; Size: Word; out Result: TPointerDynArray; out Number: Byte);
begin
  Result := nil; // unnecessary: dynamic out parameters are initialized to zero by compiler
  ...
end;

答案 2 :(得分:2)

当您在参数声明中说array of X时,您所拥有的是开放阵列,而不是动态数组。按照Bassfriend的建议并为您的数组声明一个命名类型,然后在参数声明中使用该类型。

type
  TPointerArray = array of Pointer;

procedure SeparatePackets(packet: Pointer;
                          size: Word;
                          out Result: TPointerArray;
                          out number: Byte);

number参数中没有太多意义。动态数组已经知道它们自己的长度,因此数组本身就足够了。您不需要单独的长度值,至少不需要作为输出参数。此外,Byte不是用于保持数组长度的非常好的类型。当阵列有超过255个元素时,你就遇到了麻烦。最后,因为这个函数唯一能做的就是构造一个数组,把它变成一个函数似乎更有意义:

function SeparatePackets(packet: Pointer; size: Word): TPointerArray;

答案 3 :(得分:1)

我现在无法测试,但我会尝试一个临时(本地)数组然后,作为最后一行:

Result := temp; 

<击> 另一方面,增加1是非常低效的,你可以改为100左右的增量(并跟踪使用了多少)。

答案 4 :(得分:0)

bassfriend和TOndrej已经向您展示了解决方案。有关背景信息,请阅读this - 尤其是标题为“混淆”的部分。