Alças

Até duas partes na descrição da cadeia de caracteres de formato de um identificador de endereço de procedimento. A primeira parte é o campo handle_type<1> da descrição de um procedimento, usado para indicar identificadores implícitos. Essa parte está sempre presente. A segunda parte é uma descrição de parâmetro de qualquer identificador explícito no procedimento. Ambos são explicados nas seções a seguir, juntamente com uma discussão sobre o suporte adicional do compilador MIDL da estrutura do Descritor stub para problemas de identificador de associação.

Identificadores implícitos

Se um procedimento usar um identificador implícito para associação, o campo handle_type<1> da descrição do procedimento conterá um dos três valores não zero válidos. O suporte do compilador MIDL para identificadores implícitos é encontrado no campo IMPLICIT_HANDLE_INFO da estrutura descritor 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;

Se o procedimento usar um identificador automático, o membro pAutoHandle conterá o endereço da variável stub defined–auto handle.

Se o procedimento usar um identificador primitivo implícito, o membro pPrimitiveHandle conterá o endereço da variável de identificador primitivo definida por stub.

Por fim, se o procedimento usar um identificador genérico implícito, o membro pGenericBindingInfo manterá o endereço do ponteiro para a estrutura de GENERIC_BINDING_INFO correspondente. A estrutura de dados MIDL_STUB_DESC contém um ponteiro para uma coleção de estruturas GENERIC_BINDING_PAIR . A entrada na posição zero dessa coleção é reservada para as rotinas de associação e desassociada correspondentes ao identificador de associação genérico referenciado por pGenericBindingInfo no IMPLICIT_HANDLE_INFO. O tipo de identificador de associação implícita é indicado na cadeia de caracteres de formato.

Identificadores explícitos

Há três tipos de identificador explícitos possíveis: contexto, genérico e primitivo. No caso de um identificador explícito (ou um identificador de contexto somente [out], que é tratado da mesma maneira), as informações do identificador de associação aparecem como um dos parâmetros do procedimento. As três descrições possíveis são as seguintes.

Primitivo

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

O sinalizador<1> indica se o identificador é passado por um ponteiro.

O deslocamento 2> fornece o deslocamento do início da pilha para o identificador<primitivo.

Observação

Uma descrição de identificador primitivo na cadeia de caracteres de formato de tipo é reduzida a um único FC_IGNORE.

 

Genérico

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

O flag_and _size<1> tem a mordisca da bandeira superior e a mordisca de tamanho inferior. O sinalizador indica se o identificador é passado por um ponteiro. O campo de tamanho fornece o tamanho do tipo de identificador definido pelo usuário– genérico. Esse tamanho é limitado a 1, 2 ou 4 bytes em sistemas de 32 bits e 1, 2, 4 ou 8 bytes em sistemas de 64 bits.

O campo deslocamento<2> fornece o deslocamento do início da pilha do ponteiro para os dados do tamanho fornecido.

O campo binding_routine_pair_index<1> fornece o índice para o campo aGenericBindingRoutinePairs do Descritor stub para os ponteiros de função de rotina de associação e desassociação para o identificador genérico.

Observação

Uma descrição de identificador genérico no formato de tipo é apenas a descrição do tipo de dados relacionado.

 

Contexto

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

Os sinalizadores<1> indicam como o identificador é passado e que tipo ele é. Os sinalizadores válidos são mostrados na tabela a seguir.

Hex Sinalizador
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

 

Os quatro primeiros sinalizadores sempre estiveram presentes, os últimos quatro foram adicionados ao Windows 2000.

O campo deslocamento<2> fornece o deslocamento do início da pilha para o identificador de contexto.

O context_rundown_routine_index<1> fornece um índice no campo apfnNdrRundownRoutines do Descritor stub para a rotina de rundown usada para esse identificador de contexto. O compilador sempre gera um índice. Para rotinas que não têm uma rotina de resumo, esse é um índice para uma posição de tabela que contém nulo.

Para stubs internos –Oi2, o param_num<1> fornece a contagem ordinal, começando em zero, especificando qual identificador de contexto ele está no procedimento fornecido.

Para versões anteriores do interpretador, o param_num<1> fornece o número de parâmetro do identificador de contexto, começando em zero, em seu procedimento.

Observação

Uma descrição do identificador de contexto na cadeia de caracteres de formato de tipo não terá o deslocamento<2> na descrição.

 

O novo cabeçalho –Oif

Conforme mencionado anteriormente, o cabeçalho –Oif se expande no cabeçalho –Oi . Para sua conveniência, todos os campos são mostrados aqui:

(O cabeçalho antigo)

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

(As extensões –Oif )

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

O constant_client_buffer_size<2> fornece o tamanho do buffer de marshaling que poderia ter sido pré-calculado pelo compilador. Isso pode ser apenas um tamanho parcial, pois o sinalizador ClientMustSize dispara o dimensionamento.

O constant_server_buffer_size<2> fornece o tamanho do buffer de marshaling conforme pré-compilado pelo compilador. Isso pode ser apenas um tamanho parcial, pois o sinalizador ServerMustSize dispara o dimensionamento.

Os INTERPRETER_OPT_FLAGS são definidos em 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;
  • O bit ServerMustSize será definido se o servidor precisar executar uma passagem de dimensionamento de buffer.
  • O bit ClientMustSize será definido se o cliente precisar executar uma passagem de dimensionamento de buffer.
  • O bit HasReturn será definido se o procedimento tiver um valor retornado.
  • O bit HasPipes será definido se o pacote de pipe precisar ser usado para dar suporte a um argumento de pipe.
  • O bit HasAsyncUuid será definido se o procedimento for um procedimento DCOM assíncrono.
  • O bit HasExtensions indica que as extensões do Windows 2000 e posteriores são usadas.
  • O bit HasAsyncHandle indica um procedimento RPC assíncrono.

O bit HasAsyncHandle foi inicialmente usado para uma implementação DCOM diferente de suporte assíncrono e, portanto, não pôde ser usado para o suporte assíncrono de estilo atual no DCOM. Atualmente, o bit HasAsyncUuid indica isso.