tags:

views:

202

answers:

1

I want to upgrade my application from Indy 9 to 10 with Delphi 2007. In this thread there is a call to Indy9 TIdUDPBase.SendBuffer but this won't compile in Indy10 as the method parameter don't exists. The third parameter aBuffer is a var parameter and I didn't find any such method signature in Indy10. Any alternative method to call ?

procedure TSenderThread.Execute;
var
  vTimeData: TTimeDataRecord;
  I: Integer;
  FElapsed: Int64;
  FTimerElappsed,
  vLastTimerElappsed: Int64;
begin
  vTimeData.Size := SizeOf(TTimeDataRecord);
  vTimeData.ClientCount := 1;
  Priority := tpHighest;
  FIdUDPClient := TIdUDPClient.Create(nil);
  FIdUDPClient.BroadcastEnabled := True;
  try
    while not (Terminated or Application.Terminated) do
    begin
      Sleep(1000);
      //Measure Time frame
      vLastTimerElappsed := FTimerElappsed;
      QueryPerformanceCounter(FTimerElappsed);
      FElapsed := ((FTimerElappsed-vLastTimerElappsed)*1000000) div FFrequency;
      vTimeData.TotalTimeFrame := FElapsed;
      if FRunning then
      begin
        FElapsed := ((FTimerElappsed-FStart)*1000000) div FFrequency;
        vTimeData.CurrentMessageTime := FElapsed;
      end
      else
        vTimeData.CurrentMessageTime := 0;
      //Copy Values
      vTimeData.AccumulatedTime := InterlockedExchange(TimeData.AccumulatedTime,0);
      vTimeData.MessageCount := InterlockedExchange(TimeData.MessageCount,0);
      for I := 0 to TimeClassMax do
        vTimeData.TimeClasses[I] := InterlockedExchange(TimeData.TimeClasses[I],0);

       // Calls procedure TIdUDPBase.SendBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
       // This is changed in Indy10, unable to compile  
      FIdUDPClient.SendBuffer('255.255.255.255', UIPerfPort, vTimeData, TimeData.Size);
    end;
  finally
    FreeAndNil(FIdUDPClient);
  end;
end;

EDIT: vTimeData is basically an array of integers.

  TTimeDataRecord = record
    Size: Integer; //Size of record structure is transfered and compared for safty reasons.
    ClientCount: Integer;
    AccumulatedTime: Integer; //This is the accumulated time busy in microseconds
    CurrentMessageTime: Integer; //This is the time the current message has been processed. If several computers report a high value at the same time it indicates a freeze!
    TotalTimeFrame: Integer; //This is the total time measured in microseconds
    MessageCount: Integer;
    TimeClasses: array [0..TimeClassMax] of Integer;
  end;
A: 

you have a method with same name

procedure TIdUDPClient.SendBuffer(const AHost: string; const APort: TIdPort;
  const ABuffer: TIdBytes);

Instead of an untyped buffer it expects an array of bytes. What is your data like? You just need to write your data as an array of bytes. Something like:

var
 Buffer: TIdBytes;
begin
 SetLength(Buffer, YourSizeOfData);
 Move(YourData, Buffer[0], YourSizeOfData);
 FIdUDPClient.SendBuffer('255.255.255.255', UIPerfPort, Buffer);
end;

But as I said it depends on the type of the data. The approach is ok however.

EDIT:

Now that I can see that you have a record you have two options:

Just move the whole record to array of bytes.

Move(@aRecord, Buffer[0], (6 + TimeClassMax) * SizeOf(Integer));

Have a CopyToBytes method in your record that does the actual copy. More general I guess.

TTimeDataRecord = record
  Size: Integer; //Size of record structure is transfered and compared for safty reasons.
  ClientCount: Integer;
  AccumulatedTime: Integer; //This is the accumulated time busy in microseconds
  CurrentMessageTime: Integer; //This is the time the current message has been  processed. If several computers report a high value at the same time it indicates a freeze!
  TotalTimeFrame: Integer; //This is the total time measured in microseconds
  MessageCount: Integer;
  TimeClasses: array [0..TimeClassMax] of Integer;
  procedure CopyToBytes(var Buffer: TIdBytes);
end

Implementation of the CopyToBytes

procedure TTimeDataRecord.CopyToBytes(var Buffer: TIdBytes);
begin
  // copy the data however you see fit
end;
Runner
It is a record, see the update but it contains only integers. Maybe I can typecast it to TIdBytes or must I copy it to another buffer of type TIdBytes ?
Roland Bengtsson
Yes you must copy it. See my updated response.
Runner
Thanks, this make sense.
Roland Bengtsson
FYI, Indy 10 has RawToBytes() and BytesToRaw() functions for converting TIdBytes values from/to raw memory blocks.
Remy Lebeau - TeamB