2013-02-11 14 views
6

Birden bayt/bayt diziler içeren bir kayıt var: Delphi: kaydındaki bayt döngü

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; 

Ben bu tip tek bir kayıt var ve içeride bayt üzerinde döngü gerekir (oluşturma sağlama toplamına her bayt ekleyerek basit bir sağlama toplamı). Bunu bir döngü içinde yapmak için basit bir yol var mı yoksa kayıttaki her bir unsuru tek tek gözden geçirmem gerekecek mi?

cevap

8

Sen gibi bir şey yapabilirsiniz: TRdmPacket tüm alanları bayt veya bayt diziler ve onlar ayarlanmadığı için bu özel durumda

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; 

, o düzgün çalışacaktır. Başka bir kayıt türü için bu yöntemi kullanmak istiyorsanız, Packed ve $Align directive'un dahili kayıt düzenini nasıl etkilediğini daha fazla okuyun. O sırada da

+1

için mutlak direktifini kullanabilirsiniz, bu kayıttaki her alan hizalama 1 sahiptir ve dolu sanki çok onun düzeni aynı olacaktır. Hizalama konusunda çok iyi bir noktaya değiniyorsunuz, bu burada kritik. –

+0

Tüm alanlar bayt veya bayt dizileri ise hizalama önemli değildir – kludg

+0

Çok çalışkan, gerçekten hızlı yardım için teşekkürler. – user2060821

2

Bu

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;