Search code examples
delphiudpdelphi-7delphi-10.3-rio

Incompatible parameter list when converting from Delphi 7 to Delphi 10.3


I have this app that I'm trying to convert, but I have some issues with server communication. This line:

procedure UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);

that gives me this error:

The UDPServerUDPRead method referenced by UDPServer.OnUDPRead has an incompatible parameter list. Remove the reference?

That procedure is used like this:

procedure TFrmMain.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
  Buffer: Tarray1024ofChar ;
  count: Integer;
begin
  count := AData.Size;
  if count > Length(Buffer) then exit;
  AData.Read(Buffer, count);
  if UDPServerActive then DataReceived(count,ABinding.PeerIP,ABinding.PeerPort,Buffer);
end;

What is wrong with it? What should I change?


Solution

  • The signature of the TIdUDPServer.OnUDPRead event changed from Indy 9 to Indy 10.

    In Indy 9, when a data packet arrives, you are given a TStream object wrapping the raw data.

    In Indy 10, when a data packet arrives, you are given a TIdBytes byte array of the raw data.

    So you need to update your code accordingly, eg:

    type
      // Char is a 1-byte AnsiChar in D7, but is a 2-byte WideChar in D2009+!
      Tarray1024ofChar = array[0..1023] of AnsiChar{Char} // or, use Byte instead...
    
    ...
    
    procedure TFrmMain.UDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
    var
      Buffer: Tarray1024ofChar;
      count: Integer;
    begin
      count := Length(AData);
      if count > Length(Buffer) then exit;
      BytesToRaw(AData, Buffer, count);
      if UDPServerActive then
        DataReceived(count, ABinding.PeerIP, ABinding.PeerPort, Buffer);
    end;
    

    If you can change DataReceived() to accept a PAnsiChar (or PByte) instead of a Tarray1024ofChar, you can simplify the code further by getting rid of the local Buffer variable altogether:

    procedure TFrmMain.UDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
    begin
      if UDPServerActive then
        DataReceived(Length(AData), ABinding.PeerIP, ABinding.PeerPort, PAnsiChar{PByte}(AData));
    end;