[Lazarus] Why is setlength not allowed?

Bo Berglund bo.berglund at gmail.com
Sat Nov 16 10:45:56 CET 2019


On Sat, 16 Nov 2019 09:20:28 +0100 (CET), Michael Van Canneyt via
lazarus <lazarus at lists.lazarus-ide.org> wrote:

>
>
>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;
>

Thanks so much! Now working.

But I have another issue, a warning from the compiler:

function InitI2cDevice(devpath: String; iDevAddr: Cint; var hInst:
Integer): Integer;
var
  iio : integer;
begin
  try
    hInst := fpopen(devpath, O_RDWR);                       //Open the
I2C bus in Read/Write mode
    iio := FpIOCtl(hInst, I2C_SLAVE, Pointer(iDevAddr));    //Set
options
    if (iio = 0) and (hInst > 0) then
      Result := hInst
    else
      Result := -1;
  except
    Result := -1;
  end;
end;

In this case I get a warning:
rpii2ccomm.pas(80,38) Hint: Conversion between ordinals and pointers
is not portable

It is on the line:
iio := FpIOCtl(hInst, I2C_SLAVE, Pointer(iDevAddr));

I guess that the reason is that fpIoCtrl expects a pointer type
variable so the typecast is done... Is there no alternative?

(As you might suspect I am trying to adapt code found on the Internet
in my unit for I2C communication....)


-- 
Bo Berglund
Developer in Sweden



More information about the lazarus mailing list