I have a record that contains multiple bytes/arrays of bytes:
type
TRdmPacket = record
sc: byte;
subSc: byte;
msgLength: byte;
destUID: array[0..5] of byte;
srcUID: array[0..5] of byte;
transNum: byte;
portID: byte;
msgCount: byte;
subDevice: array[0..1] of byte;
cc: byte;
pid: array[0..1] of byte;
pdl: byte;
end;
I have a single record of this type and I need to loop over the bytes inside (to create a simple checksum by adding each byte to the checksum). Is there a simple way to do this in a loop or will I need to go over each element inside the record individually?
You can do something like:
var
sum: Byte;
ptr: PByte;
i: Integer;
begin
sum := 0;
ptr := PByte(@rdmPacket);
for i := 0 to SizeOf(TRdmPacket) - 1 do
begin
sum := sum xor ptr^;
Inc(ptr);
end;
end;
In this particular case, it will work correctly, because all fields in TRdmPacket
are bytes or arrays of bytes and they are not aligned. Read further how Packed and $Align directive affects internal record layout in case you want to use this method for other type of records.
You can use the absolute directive for this
type
TRdmPacket = record
sc: byte;
subSc: byte;
msgLength: byte;
destUID: array[0..5] of byte;
srcUID: array[0..5] of byte;
transNum: byte;
portID: byte;
msgCount: byte;
subDevice: array[0..1] of byte;
cc: byte;
pid: array[0..1] of byte;
pdl: byte;
end;
Function GetPackChecksum( pack:TRdmPacket):Integer;
var
BArray:Array [0..SizeOf(TRdmPacket) - 1] of Byte absolute pack;
i:Integer;
begin
Result := 0;
for I := Low (BArray)to High(BArray) do
begin
Result := Result + BArray[i];
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
pack:TRdmPacket;
begin
ZeroMemory(@pack,SizeOf(Pack));
pack.sc := 100;
pack.destUID[1] := 123;
Showmessage(IntToStr(GetPackChecksum(pack)));
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With