Partager via


Unions RPC

Les unions encapsulées et non encapsulées partagent un format de union_arm_selector<> commun :

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>

Le champ union_arms<2> se compose de deux parties. Si l’union est une union de style MIDL 1.0, les 4 bits supérieurs contiennent l’alignement du bras d’union (alignement du plus grand bras aligné). Sinon, les 4 bits supérieurs sont zéro. Les 12 bits inférieurs contiennent le nombre d’armes dans l’union. En d’autres termes :

alignment<highest nibble> arm_counter<three lower nibbles>

Les champs offset_to_arm_description<2> contiennent un décalage signé relatif à la description de type du bras. Toutefois, le champ est surchargé avec une optimisation pour les types simples. Pour cela, l’octet supérieur de ce champ de décalage est FC_MAGIC_UNION_BYTE (0x80) et l’octet inférieur du court est le type de caractère de format réel du bras. Par conséquent, il existe deux plages pour les valeurs de décalage : « 80 xx» signifie que xx est une chaîne de format de type ; et tout le reste dans la plage (80 FF .. 7f FF) signifie un décalage réel. Cela rend les décalages de la plage <80 00 .. 80 FF > indisponibles en tant que décalages. Le compilateur vérifie qu’à partir de MIDL version 5.1.164.

Le champ default_arm_description<2> indique le type de bras d’union pour le bras par défaut, le cas échéant. S’il n’existe aucun bras par défaut spécifié pour l’union, le champ default_arm_description<2> est 0xFFFF et une exception est levée si la valeur switch_is ne correspond à aucune des valeurs de cas arm. Si le bras par défaut est spécifié mais vide, le champ default_arm_description<2> est égal à zéro. Sinon, le champ default_arm_description<2> a la même sémantique que les champs offset_to_arm_description<2>.

Voici un résumé :

  • 0 - valeur par défaut vide
  • FFFF - aucune valeur par défaut
  • 80xx - type simple
  • autre - décalage relatif

Unions encapsulées

Une union encapsulée provient d’une syntaxe d’union spéciale dans IDL. En fait, une union encapsulée est une structure groupée avec un champ discriminant au début de la structure et de l’union comme seul autre membre.

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

Le champ switch_type<1> d’une union encapsulée comporte deux parties. Le nibble inférieur fournit le type de commutateur réel, et le nibble supérieur fournit l’incrément de mémoire pour effectuer un pas à pas, c’est-à-dire une quantité que le pointeur de mémoire doit être incrémenté pour ignorer le champ switch_is, qui inclut tout remplissage entre le champ switch_is() de la structure construite par stub et le champ d’union réel.

Le champ memory_size<2> est la taille de l’union uniquement et est identique aux unions noncapsulées. Pour obtenir la taille totale de la structure qui contient l’union, ajoutez memory_size<2> à l’incrément de la mémoire pour effectuer un pas à pas, c’est-à-dire au nibble supérieur du champ switch_type<1>, puis aligner par l’alignement correspondant à l’incrément.

Unions non récapsulées

Une union non récapsulée est une situation typique où une union est un argument ou un champ et que le commutateur est un autre argument ou champ, respectivement.

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

Où:

Le champ switch_type<1> est un caractère de format pour le discriminant.

Le champ switch_is_descriptor<> est un descripteur de corrélation et a 4 ou 6 octets selon que /robuste est utilisé. Toutefois, pour l’switch_is_description<>, si l’union est incorporée dans une structure, le champ de décalage de l’switch_is_description<> est le décalage vers le champ switch_is de la position de l’union dans la structure (et non à partir du début de la structure).

Le champ offset_to_size_and_arm_description<2> donne le décalage à la description de la taille et du bras de l’union, identique à celle des unions encapsulées et partagée par toutes les unions non regroupées du même type :

memory_size<2> 
union_arm_selector<>