Прочитать на английском

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


Маркеры

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

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

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

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 содержит адрес переменной заглушки, определенной —auto handle.

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

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

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

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

Примитивные

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

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

Поле binding_routine_pair_index<1> передает индекс в полеGenericBindingRoutinePairs дескриптора stub для указателей функции bind и unbind для универсального дескриптора.

Примечание

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

 

Контекст

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

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

Hex Flag
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 дескриптора заглушки для подпрограммы запуска, используемой для этого дескриптора контекста. Компилятор всегда создает индекс. Для подпрограмм, которые не имеют подпрограммы запуска, это индекс для позиции таблицы, в которой содержится значение NULL.

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

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

Примечание

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

 

Заголовок New –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 в настоящее время указывает на это.