Freigeben über


Zeigerlayout

Das Zeigerlayout beschreibt Zeiger einer Struktur oder einer MATRIX.

pointer_layout<>

Ein pointer_layout<> Feld besteht aus den Formatzeichen FC_PP FC_PAD gefolgt von einer oder mehreren Zeigerbeschreibungen, wie später beschrieben und mit einem FC_END Formatzeichen beendet wird:

FC_PP
FC_PAD
{ pointer_instance_layout<> }*
FC_END

Ein pointer_instance_layout-Feld<> ist eine Formatzeichenfolge, die einzelne oder mehrere Instanzen von Zeigern beschreibt. Die folgenden Felder werden in diesen Deskriptoren verwendet:

  • offset_in_memory

    Der signierte Offset auf die Position des Zeigers im Arbeitsspeicher. Bei einem Zeiger, der sich in einer Struktur befindet, ist dieser Offset ein negativer Offset vom Ende der Struktur (das Ende des nichtkonformanten Teils der konformen Strukturen); für Arrays liegt der Offset vom Anfang des Arrays.

  • offset_in_buffer

    Der signierte Offset zur Position des Zeigers im Puffer. Bei einem Zeiger, der sich in einer Struktur befindet, ist dieser Offset ein negativer Offset vom Ende der Struktur (das Ende des nichtkonformanten Teils konformer Strukturen): Bei Arrays liegt der Offset vom Anfang des Arrays.

  • offset_to_array

    Versetzt von einer umschließenden Struktur auf das eingebettete Array, dessen Zeiger behandelt werden. Bei Arrays auf oberster Ebene ist dieses Feld immer null.

  • iterations

    Die Gesamtzahl der Zeiger, die dasselbe Layout<> aufweisen.

  • increment

    Inkrementierung zwischen aufeinander folgenden Zeigern während eines WIEDERHOLUNGSVORGANGS.

  • number_of_pointers

    Anzahl der verschiedenen Zeiger in einer Wiederholungsinstanz.

  • pointer_description

    Zeigerbeschreibung.

Alle Zeigerinstanzlayouts verwenden die folgenden einzelnen pointer_instance<8>:

offset_to_pointer_in_memory<2> 
offset_to_pointer_in_buffer<2> 
pointer_description<4>

Nachfolgend sind Instanzdeskriptoren aufgeführt:

Einzelne Instanz eines Zeigers auf einen einfachen Typ:

FC_NO_REPEAT FC_PAD 
pointer_instance<8>

Fester Wiederholungszeiger:

FC_FIXED_REPEAT FC_PAD 
iterations<2> 
increment<2> 
offset_to_array<2> 
number_of_pointers<2>
{ pointer_instance<8> }*

Variabler Wiederholungszeiger:

FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET) 
increment<2> 
offset_to_array<2> 
number_of_pointers<2> 
{ pointer_instance<8> }*

Für feste Wiederholungs- und variablen Wiederholungszeigerinstanzen gibt es eine Reihe von Offset- und Zeigerbeschreibungen für jeden Zeiger in der Wiederholungsinstanz.

Probleme beim Entwurf des Zeigerslayouts

In diesem Abschnitt werden Probleme im Zusammenhang mit der Verarbeitung konformer Strukturen und eingebetteter Zeiger behandelt. Das Problem besteht darin, dass der Compiler Zeigerlayouts für Strukturen und Arrays mit einiger Redundanz generiert. Dies ist von Vorteil, da die Informationen nützlich sind und beispielsweise eine konforme Struktur einen Zeigerlayout durchlaufen kann, um alle Zeiger von der Struktur und vom konformen Array zu bedienen, das Teil der konformen Struktur ist. Es gibt jedoch einige eingebettete Situationen, in denen das NDR-Modul zusätzliche Arbeit ausführt, um alle Zeigerlayouts in der richtigen Reihenfolge zu verarbeiten, wobei jeder Zeiger genau einmal verarbeitet wird.

Was der Compiler generiert

Jedes in diesem Abschnitt erläuterte Objekt weist Zeiger auf, z. B. weist eine konforme Struktur Zeiger in der Strukturkomponente sowie in den Arrayelementen auf. Das Element ist eine einfache Struktur mit einem Zeiger.

  1. Konforme Struktur, einzelne Ebene

    Der konforme Deskriptor verfügt über einen PP-Teil, in dem alle Zeiger beschrieben werden, sowohl aus der Struktur als auch aus dem Array. Die Memberliste hat FC_LONG anstelle eines Zeigers. Der CARRAY-Arraydeskriptor verfügt über Elemente über die Verwendung eines embedded_complex und überhaupt keine Zeigerdeskriptoren. Das Element verfügt weiterhin über einen einzelnen Zeigerdeskriptor. Das Zeigerlayout steht vor dem Elementlayout in einer konformen Struktur und einfachen Strukturdeskriptoren.

  2. Konforme Struktur, mindestens zwei Ebenen

    Die PP-Beschreibung enthält Zeiger aller Ebenen. Sie verwendet dieselbe Arraybeschreibung wie die interne konforme Struktur. Die Memberliste hat FC_LONG anstelle eines Zeigers. Eine eingebettete Struktur entsteht durch die Verwendung eines eingebetteten Komplexes. Der konforme Strukturdeskriptor wird wie folgt wiederverwendet. Die Größe des flachen Teils der Struktur ist ebenfalls vollständig, was bedeutet, dass die Strukturgröße der obersten Ebene die flache Größe der eingebetteten Struktur enthalten würde.

  3. Komplexe Struktur, einzelne Ebene

    Zeigermitglieder werden durch FC_POINTER markiert. Das Zeigerlayout wird vereinfacht, sodass für jeden FC_POINTER Eintrag in der Liste ein Zeigerdeskriptor (4 Byte) vorhanden ist. Das Zeigerlayout wird parallel zu einem Member-Walk geführt, d. h. ein FC_POINTER bewirkt, dass die nächste Zeigerbeschreibung verarbeitet wird. Das CARRAY-Array verfügt über ein Zeigerlayout mit allen Deskriptoren des Arrays und anschließend über die Verwendung eines eingebetteten Komplexes. Der Elementdeskriptor wird wiederverwendet. Die Größe des flachen Teils der Struktur ist vollständig; Anders ausgedrückt: Die flache Größe der Struktur auf oberster Ebene enthält die flache Größe der eingebetteten Struktur. Das Elementlayout steht vor dem Zeigerlayout für komplexe Strukturen.

    Daher unterscheidet sich die Generierung der konformen Arraybeschreibung je nachdem, ob es sich um ein Array innerhalb einer konformen Struktur oder innerhalb einer komplexen Struktur handelt.

  4. Komplexe Struktur, 2 oder mehr Ebenen, komplex in komplexen

    Komplexe Struktur auf oberster Ebene hat seine Memberzeiger, eingebettete komplexe Struktur hat seine Memberzeiger. Der konforme Strukturdeskriptor wird wiederverwendet. Der Arraydeskriptor von oben ist das wiederverwendete Array aus der eingebetteten Struktur.

  5. Komplexe Struktur mit eingebetteter konformer Struktur

    Die Konformitätsstruktur auf oberster Ebene weist die Memberzeiger auf. Der konforme Strukturdeskriptor wird wie folgt wiederverwendet. Der Arraydeskriptor wird aus der eingebetteten konformen Struktur wiederverwendet; Mit anderen Worten, es hat keine Zeiger am Arraydeskriptor. Das Element weist den Zeigerdeskriptor auf.

  6. Arrays von Strukturen mit Zeigern

    Ein Array einfacher Strukturen mit Zeigern wird als SMFARRAY oder CARRAY generiert, je nachdem, ob das Array angepasst ist, aber in beiden Fällen verfügt es über ein vollständiges Zeigerlayout (FIXED_REPEAT oder VARIABLE_REPEAT). Das Zeigerlayout wird vor dem Elementlayout angezeigt.

    Ein Array komplexer Strukturen mit Zeigern wird als BOGUS_ARRAY generiert, unabhängig davon, ob es fest oder groß ist und in beiden Fällen kein Zeigerlayout hat.

Funktionsweise des NDR-Moduls

In diesem Abschnitt wird das Verhalten des NDR-Moduls beschrieben.

Der Marshallingpass

  1. Konforme Strukturen und eingebettete konforme Struktur.

    Die Struktur der obersten Ebene verhält sich wie eine Struktur mit einer Ebene.

  2. Eingebettete komplexe Struktur mit konformer Matrix

    Jede komplexe Struktur zwingt die äußere Struktur zu einer komplexen Struktur. Eingebettete Struktur marshallt niemals sein Array. Jede Struktur durchläuft immer eingebettete Zeiger, indem sie einfach Mitglieder marshallen und ein Mitglied als FC_POINTER.

  3. Komplexe Struktur mit konformer Struktur

    Die am häufigsten eingebettete konformen Struktur marshallt das konforme Array und alle Zeiger. Das NDR-Modul geht niemals von tiefer geschachtelten konformen Strukturen ab, wenn vorhanden; dies vereinfacht die Lösung, da es sich bei einer konformen Struktur um ein Blattobjekt handelt, soweit es um das Marshalling eingebetteter Objekte geht. Die komplexe Struktur der obersten Ebene überspringt das Array-Marshalling.

Entmarshaling, Bufsizing und Freihandpass

Entmarshaling ist symmetrisch zum Marshallen; Der erste Vorgang, der für komplexe Strukturen ausgeführt wird, besteht darin, die Position der Zeiger im Puffer durch Aufrufen der NdrComplexStructBufferSize-Funktion zu ermitteln. Anschließend werden parallele Punkte umarshallt, wodurch dasselbe Schema aktiviert wird, damit die Zeiger richtig verwendet werden können. Es sollte keine Verwirrung hinsichtlich der Größe von Objekten und Gewerkschaften geben; Das Speicherbild sollte nicht für Größe von Objekten und Vereinigungen verwendet werden, nur für den Pufferinhalt.

Die Flaggen, die verwendet werden, um Marshaling und Entmarshaling korrekt durchzuführen, werden auf die gleiche Weise verwendet, um sicherzustellen, dass Zeiger genau einmal geführt werden.

Endianness pass

Zunächst ähnelt der Endianitätsdurchgang etwas dem Marshalling/Entmarshaling; Zum Verarbeiten komplexer Strukturen sind zwei Durchläufe erforderlich. Beim ersten Durchlauf wird der flache Teil konvertiert und die Position des Zeigers im Puffer gefunden, ähnlich wie die Bufsizing diesen Vorgang zum Aufheben der Verbindung ausführt. Der zweite Durchlauf konvertiert dann die Zeiger.

Endianität übergibt sich in folgender Weise: Jede Struktur und jedes Element muss gestuft werden, bis das Blattelement oder Element ein einfacher Typ ist. Dies unterscheidet sich von der Unmarshaling; in Unmarshaling, zum Beispiel, gibt es nie eine Notwendigkeit, konforme Strukturen zu verarbeiten, die in konformen Strukturen eingebettet sind, oder ein Mitglied der konformen Struktur, für dieses Thema. Ein weiteres Problem besteht darin, dass es sich bei der Konvertierung nicht um einen idempotenten Vorgang handelt. Daher könnte der Unmarshaling-Pass einige Teile ohne Schaden wiederholen, während die Konvertierung streng einmal pro einfachem Typ durchgeführt werden muss.

Daher kann der Endianitätsalgorithmus wie folgt zusammengefasst werden. Der NDR hat eine Vorstellung der konformen Struktur der obersten Ebene und eine Kennzeichnung, mit der dies entsprechend gekennzeichnet werden soll. Wenn Sie zum ersten Mal gehen, z. B. um den flachen Teil zu konvertieren und die Position der Zeiger zu erhalten, würde dieser Begriff nicht verwendet werden. NDR würde durch die flachen Teile aller Ebenen von Strukturen absteigen und sich nie in die Zeigerverarbeitung wagen. Schließlich würde NDR das Array auf oberster Ebene flach konvertieren.

Wenn Sie das zweite Mal gehen, wird die Kennzeichnung verwendet, um den Pass des eingebetteten Zeigers zu markieren, um zu vermeiden, dass tiefere Ebenen der konformen Strukturen und dann die am häufigsten konformste Struktur eingegeben werden. Auf diese Weise würde die Flagge das gemeinsame Marshaling/Unmarshaling-Verhalten erzwingen, das verhindert, dass sie in tiefere Ebenen konformer Strukturen absteigen.

Der zweite Durchgang für komplexe Strukturen mit konformen Arrays funktioniert wie folgt: Die komplexen Strukturen funktionieren auf die gemeinsame Weise; dies bedeutet, dass tiefere Ebenen niemals ihre konforme Größe oder ihre konformen Arrays betrachten oder überspringen würden und stattdessen ihre Mitglieder einfach durchlaufen würden, ohne das Array zu berühren.

Bei komplexen Strukturen mit konformen Strukturen muss die konforme Struktur wissen, ob es sich um die oberste Ebene handelt und ob sie sich in einer komplexen Struktur befindet. Der flache Teil des Arrays wird von der obersten konformsten Struktur verarbeitet. Beim zweiten Durchgang überspringt die am häufigsten konforme Struktur den flachen Teil und durchläuft das Zeigerlayout und kehrt zurück. Die am häufigsten komplexe Struktur würde ihren flachen Teil überspringen und auch das Zeigerlayout überspringen.

Der robuste Aspekt der Endianität führt

Der Endianness-Walk sucht nach den üblichen Out-of-the-Puffer-Bedingungen und führt andere Überprüfungen einer nicht korrelierte Natur durch. Die Überprüfungen auf korrelierte Werte (z. B. das Größenargument im Vergleich zur konformen Größe) können mit diesem Schritt nicht ausgeführt werden; sie werden später durchgeführt, wenn sie entmarshaling.