Профсоюзы 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<>