将指针传递给需要字节数组的例程

时间:2019-02-11 03:46:41

标签: delphi

我有在Delphi 10.1 Berlin中编译的代码,但是在Rio引发了错误。

  

“不兼容的类型ByteArray和指针。

该例程使用单个ByteArray参数定义,其中 ByteArray是定义为

的类型
type ByteArray = array of byte;

在10.1下,我可以传递一个指针或@arrayname [0]。 在10.3以下,它会给出上面的不兼容错误

interface

uses Windows, SysUtils, classes, Dialogs, Messages, Controls;

type
  ByteArray = array of byte;

procedure ArrayFunc(const P : ByteArray);
function TestFunction;

implementation

procedure ArrayFunc(const P : ByteArray);
begin    
  // code....    
end;

procedure TestFunction;    
var g : ByteArray;
begin    
  ArrayFunc(g); // works    
  Arrayfunc(@g[0]); // works under 10.1, not 10.3    
end;

end.

1 个答案:

答案 0 :(得分:5)

这是Delphi 10.2中已修复的编译器缺陷

请参见RSP 17511 E2010 Incompatible types for arrays and "Types @ operator"

来自QP:

  

这是对对象Pascal的故意更改。问题在于动态数组是托管类型,涉及引用计数和相关的辅助函数生成。

     

从@ -operator带有动态数组生成的指针会绕过引用计数机制,该机制可能会导致内存损坏。

     

可以像在此修订示例中那样,通过显式的类型转换避免这种额外的检查。

type
  TMyRec = Record
    a,b : Integer ;
  end ;

var
  e : TArray<Integer>;
  f : TArray<TMyRec>;

procedure test;
var
  a : TArray<TMyRec>;
  b : TArray<TMyRec>;
  c : TArray<Integer>;
  d : TArray<Integer>;
begin
  SetLength( b, 2) ;
  b[0].a := 123 ;
  b[1].a := 345 ;
  a := TArray<TMyRec>(@b[0]);
  f := TArray<TMyRec>(@b[0]);
  a := TArray<TMyRec>(@b);
  a := TArray<TMyRec>(@f);
  a[0] := f[0] ;

  SetLength( c, 1) ;
  d := TArray<Integer>(@c);
  e := TArray<Integer>(@c);
end;

根据您的情况更改

Arrayfunc(@g[0]);

Arrayfunc(ByteArray(@g[0]));

请注意,您不能仅将任何指针传递给ArrayFunc过程。如果指针未指向动态数组,则可能发生意外情况。

请参见此示例,该示例输出长度为零而不是两个:

Program TestDynArrPointer;
{$APPTYPE CONSOLE}

type
  ByteArray = array of byte;

procedure ArrayFunc( const arr : ByteArray);
begin
  WriteLn(Length(arr));  // Outputs zero length
end;

var
 arr : ByteArray;
begin
  SetLength(arr,2);
  ArrayFunc(ByteArray(@arr[1])); // <- Deliberately passing with an offset
  ReadLn;
end.