Partilhar via


Pegas

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 alças implícitas. Esta parte está sempre presente. A segunda parte é uma descrição de parâmetros 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 de Stub para problemas de identificador de vinculação.

Identificadores implícitos

Se um procedimento usa um identificador implícito para vinculação, o campo handle_type<1> da descrição do procedimento contém um dos três valores válidos diferentes de zero. O suporte do compilador MIDL para identificadores implícitos é encontrado no campo IMPLICIT_HANDLE_INFO da estrutura do descritor de 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 do pAutoHandle conterá o endereço da variável de identificador automático definido pelo stub.

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

Finalmente, se o procedimento usa um identificador genérico implícito, o membro pGenericBindingInfo mantém 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 desta coleção é reservada para o bind e unbind rotinas correspondentes ao identificador de ligação genérico referenciado por pGenericBindingInfo em IMPLICIT_HANDLE_INFO. O tipo de identificador de ligação implícita é indicado na cadeia de caracteres de formato.

Alças explícitas

Existem três tipos possíveis de identificador explícito: contexto, genérico e primitivo. No caso de um identificador explícito (ou um identificador de contexto [out] apenas, que é tratado da mesma maneira), as informações do identificador de ligaçã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 a alça é passada por um ponteiro.

O deslocamento<2> fornece o deslocamento do início da pilha para a alça primitiva.

Observação

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

 

Genéricos

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

O flag_and _size<1> tem o nibble da bandeira superior e o nibble de tamanho inferior. O sinalizador indica se a alça é passada por um ponteiro. O campo tamanho fornece o tamanho do tipo de identificador genérico definido pelo usuário. 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 de 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 no campo aGenericBindingRoutinePairs do Descritor de Stub para o ligar e desvincular ponteiros de função de rotina para o identificador genérico.

Observação

Uma descrição genérica do identificador 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 a alça é passada e que tipo é. Os sinalizadores válidos são mostrados na tabela a seguir.

Hex Bandeira
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 primeiros quatro sinalizadores sempre estiveram presentes, os últimos quatro foram adicionados no Windows 2000.

O campo de 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 de 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 rundown, este é um índice para uma posição de tabela que mantém null.

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

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

Como mencionado anteriormente, o cabeçalho –Oif expande-se no cabeçalho –Oi. Por 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<>]

(O –Oif extensões)

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 empacotamento 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é-calculado 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 é definido se o servidor precisar executar uma passagem de dimensionamento de buffer.
  • O bit ClientMustSize é definido se o cliente precisar executar um passo de dimensionamento de buffer.
  • O bit HasReturn é definido se o procedimento tiver um valor de retorno.
  • O bit HasPipes é definido se o pacote de pipe precisar ser usado para dar suporte a um argumento pipe.
  • O bit HasAsyncUuid é definido se o procedimento for um procedimento DCOM assíncrono.
  • O bit HasExtensions indica que o Windows 2000 e extensões posteriores são usados.
  • O bit HasAsyncHandle indica um procedimento RPC assíncrono.

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