Поделиться через


Профсоюзы 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 байт в зависимости от того, используется ли /надежный. Однако для switch_is_description<>, если объединение внедрено в структуру, поле смещения switch_is_description<> является смещением к полю switch_is от позиции профсоюза в структуре (не с начала структуры).

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

memory_size<2> 
union_arm_selector<>