Uniões RPC
As uniões encapsuladas e não encapsuladas compartilham um formato de union_arm_selector<> comum:
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>
O campo union_arms<2> consiste em duas partes. Se a união for uma união de estilo MIDL 1.0, os 4 bits superiores conterão o alinhamento do braço de união (alinhamento do braço mais alinhado). Caso contrário, os 4 bits superiores serão zero. Os 12 bits inferiores contêm o número de braços na união. Em outras palavras:
alignment<highest nibble> arm_counter<three lower nibbles>
Os campos offset_to_arm_description<2> contêm um deslocamento com sinal relativo para a descrição do tipo do braço. No entanto, o campo é sobrecarregado com otimização para tipos simples. Para eles, o byte superior desse campo de deslocamento é FC_MAGIC_UNION_BYTE (0x80) e o byte inferior do curto é o tipo de caractere de formato real do braço. Dessa forma, há dois intervalos para os valores de deslocamento: "80 xx" significa que xx é uma cadeia de caracteres de formato de tipo; e todo o resto dentro do intervalo (80 FF .. 7f FF) significa um deslocamento real. Isso faz deslocamentos do intervalo <de 80 00 .. 80 FF > indisponível como deslocamentos. O compilador verifica isso a partir da versão MIDL 5.1.164.
O campo default_arm_description<2> indica o tipo de braço de união para o braço padrão, se houver. Se não houver um braço padrão especificado para a união, o campo default_arm_description<2> será 0xFFFF e uma exceção será gerada se o valor switch_is não corresponder a nenhum dos valores de maiúsculas e minúsculas. Se o braço padrão for especificado, mas vazio, o campo default_arm_description<2> será zero. Caso contrário, o campo default_arm_description<2> tem a mesma semântica que os campos offset_to_arm_description<2> .
Veja a seguir um resumo:
- 0 – padrão vazio
- FFFF – sem padrão
- 80xx - tipo simples
- outro – deslocamento relativo
Uma união encapsulada vem de uma sintaxe de união especial no IDL. Efetivamente, uma união encapsulada é uma estrutura de pacote com um campo discriminante no início da estrutura e da união como o único outro membro.
FC_ENCAPSULATED_UNION switch_type<1>
memory_size<2>
union_arm_selector<>
O campo switch_type<1> de uma união encapsulada tem duas partes. O nibble inferior fornece o tipo de comutador real, e o nibble superior fornece o incremento de memória para percorrer essa é uma quantidade que o ponteiro de memória deve ser incrementado para ignorar o campo switch_is, que inclui qualquer preenchimento entre o campo switch_is() da estrutura construída por stub e o campo união real.
O campo memory_size<2> é do tamanho apenas da união e é idêntico a uniões não anátuladas. Para obter o tamanho total da estrutura que contém a união, adicione memory_size<2> ao incremento de memória para percorrer, ou seja, na mordisca superior do campo switch_type<1> e alinhe pelo alinhamento correspondente ao incremento.
Uma união nãocapsulada é uma situação típica em que uma união é um argumento ou campo e a opção é outro argumento ou campo, respectivamente.
FC_NON_ENCAPSULATED_UNION switch_type<1>
switch_is_description<>
offset_to_size_and_arm_description<2>
Em que:
O campo switch_type<1> é um caractere de formato para o discriminante.
O campo switch_is_descriptor<> é um descritor de correlação e tem 4 ou 6 bytes, dependendo se /robust é usado. No entanto, para o switch_is_description<>, se a união estiver inserida em uma estrutura, o campo de deslocamento da switch_is_description<> será o deslocamento para o campo switch_is da posição da união na estrutura (não desde o início da estrutura).
O campo offset_to_size_and_arm_description<2> fornece o deslocamento para o tamanho e a descrição do braço da união, que é idêntico ao de uniões encapsuladas e é compartilhado por todas as uniões não anárculas do mesmo tipo :
memory_size<2>
union_arm_selector<>