Unions RPC
Les unions encapsulées et non encapsulées partagent un format 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 2<> champs offset_to_arm_description contiennent un décalage signé relatif par rapport à la description de type du bras. Toutefois, le champ est surchargé d’optimisation pour les types simples. Pour ceux-ci, 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 ce qui se trouve dans la plage (80 FF.. 7f FF) signifie un décalage réel. Cela effectue des décalages de la plage <80 00 .. 80 FF > indisponibles en tant que décalages. Le compilateur vérifie cela à 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’y a pas de 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 de bras. 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 offset_to_arm_description<2> champs.
Voici un résumé :
- 0 - vide par défaut
- 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 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 à dépasser, c’est-à-dire une quantité que le pointeur de mémoire doit être incrémenté pour passer au-delà du champ switch_is, ce qui inclut tout remplissage entre le champ switch_is() de la structure stub-construite et le champ d’union réel.
Le champ memory_size<2> est la taille de l’union uniquement et est identique aux unions non encapsulées. Pour obtenir la taille totale de la structure qui contient l’union, ajoutez memory_size<2> à l’incrément de mémoire pour passer à pas, c’est-à-dire au nibble supérieur du champ switch_type<1> , puis alignez selon l’alignement correspondant à l’incrément.
Unions non encapsulées
Une union non encapsulée est une situation classique où une union est un argument ou un champ et 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 qui comporte 4 ou 6 octets selon que /robust est utilisé ou non. Toutefois, pour le switch_is_description<>, si l’union est incorporée dans une structure, le champ offset de l’switch_is_description<> correspond au décalage vers le champ switch_is de la position de l’union dans la structure (pas à partir du début de la structure).
Le champ offset_to_size_and_arm_description<2> donne le décalage par rapport à la taille et à la description du bras de l’union, qui est identique à celle des unions encapsulées et est partagé par toutes les unions non encapsulées du même type :
memory_size<2>
union_arm_selector<>