Unioni RPC
Le unioni incapsulate e non incapsulate condividono un formato union_arm_selector<> comune:
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>
Il campo union_arms<2> è costituito da due parti. Se l'unione è un'unione di stile MIDL 1.0, i 4 bit superiori contengono l'allineamento del braccio di unione (allineamento del braccio allineato più grande). In caso contrario, i 4 bit superiori sono zero. I 12 bit inferiori contengono il numero di braccia nell'unione. In altre parole:
alignment<highest nibble> arm_counter<three lower nibbles>
I campi offset_to_arm_description<2> contengono un offset con segno relativo alla descrizione del tipo del braccio. Tuttavia, il campo viene sottoposto a overload con ottimizzazione per i tipi semplici. Per questi, il byte superiore di questo campo di offset è FC_MAGIC_UNION_BYTE (0x80) e il byte inferiore del breve è il tipo di carattere di formato effettivo del braccio. Di conseguenza, esistono due intervalli per i valori di offset: "80 xx" significa che xx è una stringa di formato di tipo; e tutto il resto all'interno dell'intervallo (80 FF .. 7f FF) significa un offset effettivo. Ciò rende gli offset dall'intervallo <80 00 .. 80 FF > non disponibile come offset. Il compilatore verifica che a partire da MIDL versione 5.1.164.
Il campo default_arm_description<2> indica il tipo di braccio di unione per il braccio predefinito, se presente. Se non è specificato alcun braccio predefinito per l'unione, il campo default_arm_description<2> viene 0xFFFF e viene generata un'eccezione se il valore del switch_is non corrisponde ad alcun valore del case arm. Se il braccio predefinito è specificato ma vuoto, il campo default_arm_description<2> è zero. In caso contrario, il campo default_arm_description<2> ha la stessa semantica dei campi offset_to_arm_description<2> .
Di seguito è riportato un riepilogo:
- 0 - Valore predefinito vuoto
- FFFF - Nessun valore predefinito
- 80xx - tipo semplice
- other - offset relativo
Un'unione incapsulata deriva da una sintassi di unione speciale in IDL. In effetti, un'unione incapsulata è una struttura di aggregazione con un campo discriminante all'inizio della struttura e l'unione come unico altro membro.
FC_ENCAPSULATED_UNION switch_type<1>
memory_size<2>
union_arm_selector<>
Il campo switch_type<1> di un'unione incapsulata ha due parti. Il nibble inferiore fornisce il tipo di commutatore effettivo e il nibble superiore fornisce l'incremento della memoria per eseguire l'istruzione superiore, ovvero una quantità che il puntatore alla memoria deve essere incrementato per ignorare il campo switch_is, che include qualsiasi spaziatura interna tra il campo switch_is() della struttura costruita dallo stub e il campo unione effettivo.
Il campo memory_size<2> è la dimensione dell'unica unione ed è identico alle unioni non incapsulate. Per ottenere la dimensione totale della struttura che contiene l'unione, aggiungere memory_size<2> all'incremento della memoria per eseguire l'istruzione, ovvero al nibble superiore del campo switch_type<1> , quindi allinearlo in base all'allineamento corrispondente all'incremento.
Un'unione non incapsulata è una situazione tipica in cui un'unione è un argomento o un campo e l'opzione è rispettivamente un altro argomento o campo.
FC_NON_ENCAPSULATED_UNION switch_type<1>
switch_is_description<>
offset_to_size_and_arm_description<2>
Dove:
Il campo switch_type<1> è un carattere di formato per il discriminante.
Il campo switch_is_descriptor<> è un descrittore di correlazione e ha 4 o 6 byte a seconda che venga usato /robust . Tuttavia, per il switch_is_description<>, se l'unione è incorporata in una struttura, il campo offset del switch_is_description<> è l'offset al campo switch_is dalla posizione dell'unione nella struttura (non dall'inizio della struttura).
Il campo offset_to_size_and_arm_description<2> restituisce l'offset alla dimensione e alla descrizione del braccio dell'unione, identica a quella per le unioni incapsulate e condivisa da tutte le unioni non incapsulate dello stesso tipo:
memory_size<2>
union_arm_selector<>