Профсоюзы RPC

Инкапсулированные и некапсулированные объединения имеют общий формат union_arm_selector<> :

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>

Поле union_arms<2> состоит из двух частей. Если объединение является объединением в стиле MIDL 1.0, верхние 4 бита содержат выравнивание рукоять объединения (выравнивание наибольшей выровненной руки). В противном случае верхние 4 бита равны нулю. Нижние 12 бит содержат количество оружия в союзе. Другими словами:

alignment<highest nibble> arm_counter<three lower nibbles>

Поля offset_to_arm_description<2> содержат относительное смещение со знаком описания типа руки. Однако поле перегружено оптимизацией для простых типов. Для них верхний байт этого поля смещения FC_MAGIC_UNION_BYTE (0x80), а нижний байт короткого — фактический тип символа формата руки. Таким образом, существует два диапазона для значений смещения: "80 xx" означает, что xx является строкой формата типа; и все остальное в диапазоне (80 FF .. 7f FF) означает фактическое смещение. Это делает смещения из диапазона <80 00 .. 80 FF > недоступно в качестве смещения. Компилятор проверяет, что начиная с MIDL версии 5.1.164.

Поле default_arm_description<2> указывает тип руки объединения для рукоять по умолчанию, если она есть. Если для объединения не указана область по умолчанию, то поле default_arm_description<2> 0xFFFF и возникает исключение, если значение switch_is не соответствует ни одному из значений регистра arm. Если указана строка по умолчанию, но пуста, то поле default_arm_description<2> равно нулю. В противном случае поле default_arm_description<2> имеет ту же семантику, что и поле offset_to_arm_description<2> .

Ниже приведена сводка.

  • 0 — пустое значение по умолчанию
  • FFFF — нет по умолчанию
  • 80xx — простой тип
  • other — относительное смещение

Инкапсулированные союзы

Инкапсулированное объединение происходит из специального синтаксиса объединения в IDL. Фактически инкапсулированное объединение представляет собой структуру пакета с дискриминантным полем в начале структуры и объединением в качестве единственного другого члена.

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

Поле switch_type<1> инкапсулированного объединения состоит из двух частей. Нижний элемент предоставляет фактический тип переключателя, а верхний элемент — приращение памяти для пошагового перехода. Это количество, которое необходимо увеличить указатель памяти, чтобы пропустить поле switch_is, которое включает любое заполнение между полем switch_is() созданной заглушки и фактическим полем объединения.

Поле memory_size<2> является размером только союза и идентично неинкапсулированным объединениям. Чтобы получить общий размер структуры, содержащей объединение, добавьте memory_size<2> к шагу увеличения памяти, т. е. к верхнему полю switch_type<1> , а затем выровнять по выравниванию, соответствующему шагу.

Некапсулированные союзы

Некапсулированное объединение — это типичная ситуация, когда объединение является одним аргументом или полем, а переключатель — другим аргументом или полем соответственно.

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

Где:

Поле switch_type<1> является символом формата для дискриминанта.

Поле switch_is_descriptor<> является дескриптором корреляции и имеет 4 или 6 байт в зависимости от того, используется ли параметр /robust . Однако для switch_is_description<>, если объединение встроено в структуру, поле смещения switch_is_description<> представляет собой смещение switch_is поле от позиции объединения в структуре (а не от начала структуры).

Поле offset_to_size_and_arm_description<2> дает смещение размера и описания руки объединения, которое идентично описанию для инкапсулированных объединений и совместно используется всеми некапсулированными объединениями одного типа:

memory_size<2> 
union_arm_selector<>