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

Uniões Encapsuladas

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.

Uniões NãoCapsuladas

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<>