我有在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.
答案 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.