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


Ручки

До двух частей в описании строки форматирования дескрипторов адресов процедуры. Первая часть — это поле handle_type<1> описания процедуры, используемое для указания неявных дескрипторов. Эта часть всегда присутствует. Вторая часть — это описание параметра любого явного дескриптора в процедуре. Оба описаны в следующих разделах, а также обсуждение дополнительной поддержки компилятора MIDL структуры дескриптора stub для проблем с дескриптором привязки.

Неявные дескрипторы

Если процедура использует неявный дескриптор для привязки, поле handle_type<1> описания процедуры содержит одно из трех допустимых ненулевого значения. Поддержка компилятора MIDL для неявных дескрипторов находится в поле IMPLICIT_HANDLE_INFO структуры дескриптора stub:

typedef  (__RPC_FAR * GENERIC_BINDING_ROUTINE)();

typedef struct 
  {
  GENERIC_BINDING_ROUTINE  pfnBind;
  GENERIC_BINDING_ROUTINE  pfnUnbind;
  } GENERIC_BINDING_ROUTINE_PAIR;
  
typedef struct __GENERIC_BINDING_INFO 
  {
  void __RPC_FAR*          pObj;
  unsigned char            Size;
  GENERIC_BINDING_ROUTINE  pfnBind;
  GENERIC_BINDING_ROUTINE    pfnUnbind;
  } GENERIC_BINDING_INFO,  *PGENERIC_BINDING_INFO;

union 
  {
  handle_t*                pAutoHandle;
  handle_t*                pPrimitiveHandle;
  PGENERIC_BINDING_INFO    pGenericBindingInfo;
  } IMPLICIT_HANDLE_INFO;

Если процедура использует автоматический дескриптор, элемент pAutoHandle содержит адрес заглушки, определяемой переменной автоматического дескриптора.

Если процедура использует неявный примитивный дескриптор, элемент pPrimitiveHandle содержит адрес определенной переменной дескриптора, определенной примитивной.

Наконец, если процедура использует неявный универсальный дескриптор, элемент pGenericBindingInfo содержит адрес указателя на соответствующую структуру GENERIC_BINDING_INFO. Структура данных MIDL_STUB_DESC содержит указатель на коллекцию GENERIC_BINDING_PAIR структур. Запись в нулевой позиции этой коллекции зарезервирована для привязки и подпрограммы без привязки, соответствующие маркеру универсальной привязки, на который ссылается pGenericBindingInfo в IMPLICIT_HANDLE_INFO. Тип неявного дескриптора привязки указывается в строке формата.

Явные дескрипторы

Существует три возможных типа явных дескрипторов: контекст, универсальный и примитивный. В случае явного дескриптора (илииз] только дескриптор контекста, который обрабатывается таким же образом, данные дескриптора привязки отображаются как один из параметров процедуры. Ниже приведены три возможных описания.

Примитивный

FC_BIND_PRIMITIVE, flag<1>, offset<2>.

Флаг<1> указывает, передается ли дескриптор указателем.

Смещение<2> обеспечивает смещение от начала стека до примитивного дескриптора.

Заметка

Примитивное описание дескриптора в строке формата типа уменьшается до одной FC_IGNORE.

 

Родовой

FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD

Flag_and _size<1> имеет верхний флаг набитый и нижний размер набит. Флаг указывает, передается ли дескриптор указателем. Поле размера предоставляет размер определяемого пользователем типа дескриптора универсального типа. Этот размер ограничен 1, 2 или 4 байтами в 32-разрядных системах и 1, 2, 4 или 8 байтах в 64-разрядных системах.

Поле смещения<2> предоставляет смещение с начала стека указателя на данные заданного размера.

Поле binding_routine_pair_index<1> предоставляет индекс в поле aGenericBindingRoutinePairs дескриптора stub к привязке и несвязываемых указателей обычной функции для универсального дескриптора.

Заметка

Описание универсального дескриптора в формате типа — это только описание связанного типа данных.

 

Контекст

FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>

Флаги<1> указать, как передается дескриптор и какой тип он есть. Допустимые флаги показаны в следующей таблице.

Зачаровывать Флаг
80 HANDLE_PARAM_IS_VIA_PTR
40 HANDLE_PARAM_IS_IN
20 HANDLE_PARAM_IS_OUT
21 HANDLE_PARAM_IS_RETURN
08 NDR_STRICT_CONTEXT_HANDLE
04 NDR_CONTEXT_HANDLE_NO_SERIALIZE
02 NDR_CONTEXT_HANDLE_SERIALIZE
01 NDR_CONTEXT_HANDLE_CANNOT_BE_NULL

 

Первые четыре флага всегда присутствовали, последние четыре были добавлены в Windows 2000.

Поле смещения<2> предоставляет смещение от начала стека до дескриптора контекста.

Context_rundown_routine_index<1> предоставляет индекс в поле apfnNdrRundownRoutines дескриптора stub к подпрограмме rundown, используемой для этого дескриптора контекста. Компилятор всегда создает индекс. Для подпрограмм, которые не имеют подпрограммы запуска, это индекс в положение таблицы, в которой содержится значение NULL.

Для заглушки, встроенных в –Oi2, param_num<1> предоставляет порядковое число, начиная с нуля, указывая, какой дескриптор контекста он находится в данной процедуре.

Для предыдущих версий интерпретатора param_num<1> предоставляет номер параметра дескриптора контекста, начиная с нуля, в процедуре.

Заметка

Описание дескриптора контекста в строке формата типа не будет содержать смещение<2> в описании.

 

Новый заголовок Oif

Как упоминалось ранее, заголовок -Oif расширяется на заголовке –Oi. Для удобства отображаются все поля:

(Старый заголовок)

handle_type<1> 
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>  
stack_size<2>
[explicit_handle_description<>]

(Расширения –Oif)

constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>

Constant_client_buffer_size<2> предоставляет размер маршалингового буфера, который мог быть предварительно вычислен компилятором. Это может быть только частичный размер, так как флаг ClientMustSize активирует размер.

Constant_server_buffer_size<2> предоставляет размер буфера маршалинга в предварительной компиляции компилятором. Это может быть только частичный размер, так как флаг ServerMustSize активирует размер.

INTERPRETER_OPT_FLAGS определены в Ndrtypes.h:

typedef struct
  {
  unsigned char   ServerMustSize      : 1;    // 0x01
  unsigned char   ClientMustSize      : 1;    // 0x02
  unsigned char   HasReturn           : 1;    // 0x04
  unsigned char   HasPipes            : 1;    // 0x08
  unsigned char   Unused              : 1;
  unsigned char   HasAsyncUuid        : 1;    // 0x20
  unsigned char   HasExtensions       : 1;    // 0x40
  unsigned char   HasAsyncHandle      : 1;    // 0x80
  } INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS;
  • Бит ServerMustSize задается, если серверу необходимо выполнить проход по размеру буфера.
  • Бит ClientMustSize задается, если клиенту необходимо выполнить проход по размеру буфера.
  • Бит HasReturn задается, если процедура имеет возвращаемое значение.
  • Бит HasPipes задается, если пакет канала должен использоваться для поддержки аргумента канала.
  • Бит HasAsyncUuid задается, если процедура является асинхронной процедурой DCOM.
  • Бит HasExtensions указывает, что используются расширения Windows 2000 и более поздних версий.
  • Бит HasAsyncHandle указывает асинхронную процедуру RPC.

Бит HasAsyncHandle изначально использовался для другой реализации асинхронной поддержки DCOM и поэтому не может использоваться для текущей асинхронной поддержки стиля в DCOM. В настоящее время бит HasAsyncUuid указывает на это.