Wie simulieren bit-Felder in Delphi records?
Möchte ich erklären, ein record in Delphi, enthält das gleiche layout, wie es in C.
Für Interessierte : Dieser Datensatz ist Teil einer union, die in der Windows OS ist LDT_ENTRY aufnehmen. (Ich muss an dieser Datensatz in Delphi, weil ich arbeite an einer Xbox-emulator in Delphi - Projekt-Dxbx auf sourceforge).
Trotzdem, die Platte in Frage wird definiert als:
struct
{
DWORD BaseMid : 8;
DWORD Type : 5;
DWORD Dpl : 2;
DWORD Pres : 1;
DWORD LimitHi : 4;
DWORD Sys : 1;
DWORD Reserved_0 : 1;
DWORD Default_Big : 1;
DWORD Granularity : 1;
DWORD BaseHi : 8;
}
Bits;
Soweit ich weiß, gibt es keine bit-Felder möglich in Delphi. Ich habe versucht dies:
Bits = record
BaseMid: Byte; // 8 bits
_Type: 0..31; // 5 bits
Dpl: 0..3; // 2 bits
Pres: Boolean; // 1 bit
LimitHi: 0..15; // 4 bits
Sys: Boolean; // 1 bit
Reserved_0: Boolean; // 1 bit
Default_Big: Boolean; // 1 bit
Granularity: Boolean; // 1 bit
BaseHi: Byte; // 8 bits
end;
Aber ach: es ist die Größe wird von 10 bytes, statt der erwarteten 4.
Ich würde gerne wissen, wie ich sollte erklären, den Datensatz, so dass ich eine Aufnahme erhalten, die das gleiche layout, die gleiche Größe und den gleichen Mitgliedern. Vorzugsweise ohne Lasten von getter/setter.
TIA.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vielen Dank an alle!
Basierend auf diesen Informationen, die ich reduziert auf :
Der index ist wie folgt codiert :
(BitOffset shl 8) + NrBits
. Wo 1<=NrBits<=32 und 0<=BitOffset<=31Jetzt kann ich Sie bekommen und setzen Sie diese bits wie folgt :
Ziemlich raffiniert, finden Sie nicht?!?!
PS: Rudy Velthuis nun enthalten eine überarbeitete version der dies in seinem ausgezeichneten "Fallstricke bei der Konvertierung"-Artikel.
Rudy ' s Delphi-Ecke ist die beste Ressource, die ich kenne, in Bezug auf Delphi und C/C++ Interoperabilität. Seine Fallstricke der Konvertierung ist ziemlich viel Lesen müssen, wenn mit C/C++ APIs in Delphi. Die Kapitel werden Sie am meisten interessiert, ist Aufzeichnungen und Ausrichtung -> Bitfields, aber ich fordere Sie auf, Lesen Sie die ganze Sache von oben nach unten, zweimal. Die anderen Artikel sind definitiv Wert die Zeit-Investition, auch.
Ok, das ist mein bit-manipulation ist ein wenig eingerostet, so dass ich könnte haben drehte den bytes. Aber der folgende code gibt die Allgemeine Idee:
Naja, im Grunde muss man sich um das schmutzige mit bit-manipulation.
Warum, speziell, müssen Sie das festhalten an der Struktur?
Wenn Sie nur zu sprechen brauchen, um ein legacy-Programm, das entweder spricht in diesem Dialekt (TCP/IP oder ähnliches), oder speichert auf diese Weise Daten (Dateien, etc.), dann würde ich die Karte von einem normalen Delphi-Struktur, um eine bit-version kompatibel. In anderen Worten, würde ich einen normal strukturierten Delphi-Struktur im Speicher, und schreiben Sie den code zu schreiben und zu Lesen, dass die Struktur in einer kompatiblen Art und Weise.
Wenn Sie brauchen, um Speicherplatz zu sparen, würde ich Getter und setter zu manipulieren, dass die bits der internen Ganzzahlen oder ähnliches. Dies wird sich auf die Leistung auswirken, aber nicht viel mehr als das, was das original C-Programm würde haben, der einzige Unterschied ist, dass die bit-manipulation würde Hinzugefügt werden, indem die compiler-magic in der C-version, in der Erwägung, dass Sie müssen es selbst schreiben.
Wenn Sie nicht über viele Datensätze im Speicher, und brauchen nicht zu sprechen, um ein anderes Programm verwende ich eine Natürliche Delphi-Struktur. Trade-off für mehr Leistung wird mehr Speicher verwendet.
Aber es hängt alles von Ihren Anforderungen.
In jedem Fall, werden Sie nicht in der Lage zu sprechen der Delphi-compiler zu tun, den gleichen job für dich als C-compiler.
PACKED RECORD auf Vorschlag von anderen hier, tut das nicht, und es war nie vorgesehen. Es entfernt nur die Ausrichtung Polsterung zu setzen-Ganzzahlen auf 32-bit-Grenzen und ähnliches, aber nicht pack mehrerer Felder in einem byte.
Beachten Sie, dass ein gemeinsamer Weg, dies zu tun ist durch Delphi-SÄTZE, die Umsetzung intern unter Verwendung von bit-Feldern. Wieder, haben Sie unterschiedliche code als der C-Variante.