6

複数のバイト/バイト配列を含むレコードがあります。

  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;

このタイプの単一のレコードがあり、内部のバイトをループする必要があります (各バイトをチェックサムに追加して単純なチェックサムを作成するため)。ループでこれを行う簡単な方法はありますか、それともレコード内の各要素を個別に調べる必要がありますか?

4

2 に答える 2

8

次のようなことができます:

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;

TRdmPacketこの特定のケースでは、すべてのフィールドがバイトまたはバイトの配列であり、整列されていないため、正しく機能します。このメソッドを他のタイプのレコードに使用する場合に備えて、 Packedおよび$Align ディレクティブが内部レコード レイアウトにどのように影響するかをさらにお読みください。

于 2013-02-11T09:48:10.680 に答える
2

これには絶対ディレクティブを使用できます

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;
于 2013-02-11T10:03:28.647 に答える