Ambalare de tipuri de date complexe în delphi

În acest articol, aș dori să-i spun și arată caracteristicile de utilizare
„Seal tipuri de date complexe“ din Delphi.

Toate au avut vreodată de a face cu înregistrările. Înregistrarea a fost folosit în multe cazuri,
- pentru a crea directoare de fișiere, gruparea și prezentare
date, sistemul de programare, etc. De exemplu, deschiderea unui fișier Windows.pas
(Modulul standard se conectează la secțiunea utilizărilor), puteți găsi ceva de genul
o astfel de descriere:

_POINTL = înregistrare ambalate
x: Longint;
y: Longint;
se încheie;

TISHMisc = înregistrare ambalate
caz de Integer // Este folosit cu opțiuni de intrare
0: (PhysicalAddress: DWORD);
1: (VirtualSize: DWORD);
se încheie;

Ceea ce denotă aici ambalate cuvântul cheie? cuvânt pachet spune Delphi
minimiza de memorie. Deci, se pare, fără ca acest cuvânt în structura noastră
Este nevoie de mai multă memorie?

Aici este o probă de intrare:

TRecord = Înregistrare
pole1. octet;
pole2. string [4];
pole3. întreg;
pole4. Int64;
se încheie;

Să calculăm mărimea: pole1 - 1 octet, pole2 - 5 octeți (sperăm să nu
uitat 4 octeți și o dimensiune de cod sub 1), pole3 - 4 octeți, pole4 - 8 octeți.
Dacă adăugați-le primi 18 bytes. Să verificăm:

SIZE1: = sizeof (TRecord);
ShowMessage ( 'dimensiunea normală de înregistrare =' + IntToStr (SIZE1));

Surprins? Acum, adăugați cuvântul ambalat înainte de cuvânt ... Însemnați dimensiunea 18 ca
estimat mai devreme. Deci, în cazul în care ne lipsesc întregul 6 octeți. Și dacă avem
o serie de 10 de milioane de astfel de înregistrări, de exemplu, într-un director, noi
Am pierdut aproximativ 57 de megaocteți?

Să vedem de ce este așa. Pentru aceasta, am folosit built-in
disassembler în Delphi. Forma butonului arunca și handler faceți clic pe write:

Procedura TForm1.Button1Click (Expeditor: TObject);
tip
// înregistrarea normală
TRecord = Înregistrare
pole1. octet;
pole2. string [4];
pole3. întreg;
pole4. Int64;
se încheie;
// înregistrare ambalate
TPackedRecord = înregistrare Prânz
pole1. octet;
pole2. string [4];
pole3. întreg;
pole4. Int64;
se încheie;

Amintiți-vă că pole1 vom atribui o valoare de până la $ FF (adică = 255), pole2 = 'hack', pole3
= $ Aaaaaaaa (4 octeți, adică = 2863311530), etc. Uită-te la poza, eu sunt pe ea
Am afișat structura octet și modul în care acestea sunt situate în memorie.

Acum, verificați înregistrarea ambalate. Rec variabilă în codul pentru a înlocui
packedRec, adică Noi folosim înregistrarea ambalate. Și facem tot același lucru:

Aici putem vedea că nici o aliniere octet nu este, și toate datele (câmp)
Ei au aranjat unul în spatele celuilalt - ambalate.

Poate întrebarea: de ce datele din primul exemplu, este aliniat cu
8-byte limita? Toată problema în setările compilator. Dacă deschideți proiectul -
Opțiunea - compilatoare (opțiuni de compilare), atunci va fi listă puțin câmp de înregistrare
aliniere, în care puteți selecta alinierea dorită (8,4,2 sau 1 octet). nu
Am uitat să rearanja proiectul după schimbare. Prin modul de aliniere a 1 octet
și există un pachet de date.

A doua întrebare este de date de ce nu este ambalat întotdeauna? Din păcate, ambalajul
Informațiile nu are numai avantaje, dar și dezavantaje. Astfel, de exemplu, alinierea la frontiera
vom mări timpul de acces la câmpuri. Prin urmare, este necesar să se utilizeze un pachet cu înțelepciune.

Apropo, în același fișier Windows.pas pot fi găsite nu numai de ambalare înregistrări, dar
și matrice, iată un exemplu:

CprMask ambalate array [0..3] de DWORD;

Încercați-vă pentru a analiza ambalajul matrice.

Arată acest articol unui prieten: