[Lazarus] Why is setlength not allowed?

Michael Van Canneyt michael at freepascal.org
Sat Nov 16 09:20:28 CET 2019



On Sat, 16 Nov 2019, Bo Berglund via lazarus wrote:

> I am trying to write a simple I2C interface program for Raspberry Pi
> but I am getting an error I don't understand...
>
> function TRaspiI2C.ReadI2CBytes(addr: integer; count: integer; buf:
> array of byte): integer;
> var
>  i: integer;
> begin
>  try
>    if count <> length(buf) then
>      SetLength (buf, count);  <== ERROR HERE!
>    for i := 0 to count -1 do
>      buf[i] := ReadI2CByte(addr + i);
>    Result := count;
>  except
>    Result := 0;
>  end;
> end;
>
> The error message states:
>
> rpii2ccomm.pas(158,7) Error: Type mismatch
>
> I have used setlength on dynamic byte arrays many times before and
> never gotten this strange error message.
> What am I doing wrong???

Because buf is not a dynamic array, but an open array.

"Open array" predates dynamic arrays, and served to be able to pass
fixed-lengh arrays of different lengths to a single function, so you would
not have to declare the same function for all array lengths.

function TRaspiI2C.ReadI2CBytes(addr: integer; count: integer; buf:  array of byte): integer;

Means you can do
type
   T10BytesArray = Array[1..10];
   T100BytesArray = Array[1..100];

var
   A10 : T10BytesArray;
   A100 : T100BytesArray;

begin
   ReadI2CBytes(1,10,A10);
   ReadI2CBytes(1,100,A100);
end;

What you need is:

  TByteArray = Array of Byte;

  function TRaspiI2C.ReadI2CBytes(addr: integer; count: integer; var buf: TByteArray): integer;


Michael.


More information about the lazarus mailing list