2013-02-11 8 views
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; 

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

答えて

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 directiveが内部レコードレイアウトにどのように影響するかをさらにお読みください。偶然にも

+1

のための絶対的なディレクティブを使用することができ、このレコード内のすべてのフィールドは、アライメント1を持っており、それが詰め込まれたかのようにそのレイアウトは同じになります。あなたはアライメントに関して非常に良い点を作っています、それはここで重要です。 –

+0

すべてのフィールドがバイトまたはバイト配列の場合は、アラインメントは関係ありません – kludg

+0

本当に速いヘルプのおかげで、うまくいきました。 – user2060821

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; 
関連する問題