Auf Englisch lesen

Freigeben über


RPC-Unions

Sowohl gekapselte als auch nicht gekapselte Unions verwenden ein gemeinsames union_arm_selector<> Format:

union_arms<2>
arm1_case_value<4> offset_to_arm_description<2>
..
armN_case_value<4> offset_to_arm_description<2>
default_arm_description<2>

Das Feld union_arms<2> besteht aus zwei Teilen. Wenn die Union eine Union im MIDL 1.0-Format ist, enthalten die oberen 4 Bits die Ausrichtung des Union-Arms (Ausrichtung des größten ausgerichteten Arms). Andernfalls sind die oberen 4 Bits null. Die unteren 12 Bits enthalten die Anzahl der Arme in der Union. Anders gesagt:

alignment<highest nibble> arm_counter<three lower nibbles>

Die offset_to_arm_description<2-Felder> enthalten einen relativen Offset mit Vorzeichen zur Typbeschreibung des Arms. Das Feld ist jedoch mit der Optimierung für einfache Typen überladen. Für diese ist das obere Byte dieses Offsetfelds FC_MAGIC_UNION_BYTE (0x80), und das untere Byte des short ist der tatsächliche Formatzeichentyp des Arms. Daher gibt es zwei Bereiche für die Offsetwerte: "80 xx" bedeutet, dass xx eine Typformatzeichenfolge ist; und alles andere im Bereich (80 FF .. 7f FF) bedeutet einen tatsächlichen Offset. Dadurch werden Offsets aus dem Bereich <80 00 .. 80 FF > als Offsets nicht verfügbar. Der Compiler überprüft dies ab MIDL-Version 5.1.164.

Das Feld default_arm_description<2> gibt den Typ des Union-Arms für den Standardarm an, sofern vorhanden. Wenn kein Standardarm für die Union angegeben ist, wird das Feld default_arm_description<2> 0xFFFF, und es wird eine Ausnahme ausgelöst, wenn der switch_is-Wert keinem der Arm-Groß-/Kleinschreibungswerte entspricht. Wenn der Standardarm angegeben ist, aber leer ist, ist das feld default_arm_description<2> null. Andernfalls weist das Feld default_arm_description<2> die gleiche Semantik wie das offset_to_arm_description<2> Felder auf.

Im Folgenden ist eine Zusammenfassung aufgeführt:

  • 0 – leerer Standardwert
  • FFFF – kein Standardwert
  • 80xx – einfacher Typ
  • Sonstiges : relativer Offset

Gekapselte Unions

Eine gekapselte Union stammt aus einer speziellen Unionsyntax in IDL. Effektiv ist eine gekapselte Union eine Bündelstruktur mit einem diskriminanten Feld am Anfang der Struktur und die Union als einziges anderes Element.

FC_ENCAPSULATED_UNION switch_type<1> 
memory_size<2>
union_arm_selector<>

Das switch_type<1-Feld> einer gekapselten Union umfasst zwei Teile. Das untere Nibble stellt den tatsächlichen Switchtyp bereit, und das obere Nibble stellt das Speicherinkrement bereit, um den Speicherzeiger zu erhöhen, um über das switch_is Feld hinauszuspringen. Dies schließt alle Abstände zwischen dem switch_is()-Feld der stub-konstruierten Struktur und dem tatsächlichen Union-Feld ein.

Das Feld memory_size<2> gibt nur die Größe der Union an und ist identisch mit nicht gekapselten Unions. Um die Gesamtgröße der Struktur zu erhalten, die die Union enthält, fügen Sie memory_size<2> zum Arbeitsspeicherinkrement hinzu, um einen Schritt zu durchlaufen, d. h. am oberen Nibble des switch_type<1-Felds> , und richten Sie dann um die Ausrichtung entsprechend dem Inkrement aus.

Nicht gekapselte Unions

Eine nicht gekapselte Union ist eine typische Situation, in der eine Union ein Argument oder Feld und der Schalter ein anderes Argument bzw. Feld ist.

FC_NON_ENCAPSULATED_UNION switch_type<1> 
switch_is_description<>
offset_to_size_and_arm_description<2>

Hierbei gilt:

Das Feld switch_type<1> ist ein Formatzeichen für die Diskriminante.

Das switch_is_descriptor<> Feld ist ein Korrelationsdeskriptor und hat 4 oder 6 Bytes, je nachdem, ob /robust verwendet wird. Wenn die Union jedoch für die switch_is_description<> in eine Struktur eingebettet ist, ist das Offsetfeld des switch_is_description<> der Offset des switch_is Felds von der Position der Union in der Struktur (nicht vom Anfang der Struktur).

Das Feld offset_to_size_and_arm_description<2> gibt den Offset zur Größen- und Armbeschreibung der Union an, die mit der für gekapselte Unions identisch ist und von allen nicht gekapselten Unions desselben Typs gemeinsam genutzt wird:

memory_size<2> 
union_arm_selector<>