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.