Condividi tramite


Selettori

Fino a due parti nella descrizione della stringa di formato di un handle di indirizzi della routine. La prima parte è il campo handle_type<1> della descrizione di una routine, usato per indicare handle impliciti. Questa parte è sempre presente. La seconda parte è una descrizione dei parametri di qualsiasi handle esplicito nella procedura. Entrambe sono illustrate nelle sezioni seguenti, insieme a una discussione sul supporto aggiuntivo del compilatore MIDL della struttura descrittore Stub per gestire i problemi di associazione.

Handle impliciti

Se una procedura usa un handle implicito per l'associazione, il campo handle_type<1> della descrizione della procedura contiene uno dei tre valori non zero validi. Il supporto del compilatore MIDL per gli handle impliciti si trova nel campo IMPLICIT_HANDLE_INFO della struttura descrittore 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 la procedura usa un handle automatico, il membro pAutoHandle contiene l'indirizzo della variabile di gestione automatica definita dallo stub.

Se la procedura usa un handle primitivo implicito, il membro pPrimitiveHandle contiene l'indirizzo della variabile di handle stub definita-primitiva.

Infine, se la procedura usa un handle generico implicito, il membro pGenericBindingInfo contiene l'indirizzo del puntatore alla struttura di GENERIC_BINDING_INFO corrispondente. La struttura dei dati MIDL_STUB_DESC contiene un puntatore a una raccolta di strutture GENERIC_BINDING_PAIR . La voce nella posizione zero di questa raccolta è riservata alle routine di associazione e senza associazione corrispondenti all'handle di associazione generico a cui fa riferimento pGenericBindingInfo in IMPLICIT_HANDLE_INFO. Il tipo di handle di associazione implicita è indicato nella stringa di formato.

Handle espliciti

Esistono tre possibili tipi di handle espliciti: contesto, generico e primitivo. Nel caso di un handle esplicito (o di un handle di contesto [out] solo, gestito nello stesso modo), le informazioni sull'handle di associazione vengono visualizzate come uno dei parametri della routine. Le tre possibili descrizioni sono le seguenti.

Primitiva

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

Il flag<1> indica se l'handle viene passato da un puntatore.

L'offset 2> fornisce l'offset<dall'inizio dello stack all'handle primitivo.

Nota

Una descrizione di handle primitiva nella stringa di formato di tipo viene ridotta a una singola FC_IGNORE.

 

Generico

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

L'flag_and _size<1> ha la nibble di bandiera superiore e il nibble di dimensioni inferiori. Il flag indica se l'handle viene passato da un puntatore. Il campo dimensioni fornisce le dimensioni del tipo di handle definito dall'utente. Questa dimensione è limitata a 1, 2 o 4 byte su sistemi a 32 bit e 1, 2, 4 o 8 byte in sistemi a 64 bit.

Il campo offset 2> fornisce l'offset<dall'inizio dello stack del puntatore ai dati delle dimensioni specificate.

Il campo binding_routine_pair_index<1> fornisce l'indice nel campo aGenericBindingRoutinePairs del descrittore Stub ai puntatori di funzione di associazione esenza associazione per l'handle generico.

Nota

Una descrizione di handle generica nel formato di tipo è la descrizione solo del tipo di dati correlato.

 

Contesto

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

I flag<1> indicano come viene passato l'handle e quale tipo è. I flag validi vengono visualizzati nella tabella seguente.

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

 

I primi quattro flag sono sempre stati presenti, gli ultimi quattro sono stati aggiunti in Windows 2000.

Il campo offset 2> fornisce l'offset<dall'inizio dello stack all'handle di contesto.

Il context_rundown_routine_index<1> fornisce un indice nel campo apfnNdrRundownRoutines del descrittore Stub alla routine di rundown usata per questo handle di contesto. Il compilatore genera sempre un indice. Per le routine che non hanno una routine di rundown, si tratta di un indice in una posizione di tabella che contiene Null.

Per gli stub compilati in –Oi2, il param_num<1> fornisce il conteggio ordinale, a partire da zero, specificando quale handle di contesto si trova nella procedura specificata.

Per le versioni precedenti dell'interprete, il param_num<1> fornisce il numero di parametro dell'handle di contesto, a partire da zero, nella relativa procedura.

Nota

Una descrizione dell'handle di contesto nella stringa di formato di tipo non avrà l'offset<2> nella descrizione.

 

Nuova intestazione -Oif

Come accennato in precedenza, l'intestazione –Oif si espande sull'intestazione –Oi . Per praticità, tutti i campi sono visualizzati qui:

(Intestazione precedente)

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

(Estensioni -Oif )

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

Il constant_client_buffer_size<2> fornisce le dimensioni del buffer di marshalling che potrebbero essere state pre-calcolate dal compilatore. Questa può essere solo una dimensione parziale, poiché il flag ClientMustSize attiva il ridimensionamento.

Il constant_server_buffer_size<2> fornisce le dimensioni del buffer di marshalling come precompilate dal compilatore. Questa può essere solo una dimensione parziale, poiché il flag ServerMustSize attiva il ridimensionamento.

La INTERPRETER_OPT_FLAGS è definita in 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;
  • Il bit ServerMustSize è impostato se il server deve eseguire un passaggio di ridimensionamento del buffer.
  • Il bit ClientMustSize è impostato se il client deve eseguire un passaggio di ridimensionamento del buffer.
  • Il bit HasReturn è impostato se la procedura ha un valore restituito.
  • Il bit HasPipes viene impostato se il pacchetto della pipe deve essere usato per supportare un argomento pipe.
  • Il bit HasAsyncUuid è impostato se la procedura è una procedura DCOM asincrona.
  • Il bit HasExtensions indica che vengono usate le estensioni di Windows 2000 e versioni successive.
  • Il bit HasAsyncHandle indica una procedura RPC asincrona.

Il bit HasAsyncHandle è stato inizialmente usato per un'implementazione DCOM diversa del supporto asincrono e quindi non è stato possibile usare per il supporto asincrono dello stile corrente in DCOM. Il bit HasAsyncUuid indica attualmente questo.