Handle di binding primitivi e personalizzati
Tutti gli handle dichiarati con i tipi handle_t o RPC_BINDING_HANDLE sono handle di associazione primitivi. È possibile estendere i tipi di handle_t o RPC_BINDING_HANDLE per includere più informazioni o informazioni diverse rispetto al tipo di handle primitivo contenuto. Quando si esegue questa operazione, si crea un handle di associazione personalizzato.
Per creare un handle di associazione personalizzato per l'applicazione distribuita, è necessario creare un tipo di dati personalizzato e specificare l'attributo [ handle] in una definizione di tipo nel file IDL. In definitiva, i file stub eseguono il mapping di handle di associazione personalizzati a handle primitivi.
Se si crea un tipo di handle di associazione personalizzato, è necessario specificare anche routine bind e unbind utilizzate dallo stub del client per eseguire il mapping di un handle personalizzato a un handle primitivo. Lo stub chiama le routine bind e unbind all'inizio e alla fine di ogni chiamata di routine remota. Le routine bind e unbind devono essere conformi ai prototipi di funzione seguenti.
Prototipo di funzione | Descrizione |
---|---|
handle_t type_bind(tipo) | Routine di associazione |
void type_unbind(type, handle_t) | Routine di annullamento dell'associazione |
L'esempio seguente mostra come è possibile definire un handle di associazione personalizzato nel file IDL:
/* usrdef.idl */
[
uuid(20B309B1-015C-101A-B308-02608C4C9B53),
version(1.0),
pointer_default(unique)
]
interface usrdef
{
typedef struct _DATA_TYPE
{
unsigned char * pszUuid;
unsigned char * pszProtocolSequence;
unsigned char * pszNetworkAddress;
unsigned char * pszEndpoint;
unsigned char * pszOptions;
} DATA_TYPE;
typedef [handle] DATA_TYPE * DATA_HANDLE_TYPE;
void UsrdefProc([in] DATA_HANDLE_TYPE hBinding,
[in, string] unsigned char * pszString);
void Shutdown([in] DATA_HANDLE_TYPE hBinding);
}
Se la routine di associazione rileva un errore, deve generare un'eccezione usando la funzione RpcRaiseException . Lo stub client eseguirà quindi la pulizia e consentirà al filtro delle eccezioni di passare al blocco di eccezioni che circonda la chiamata alla procedura remota sul lato client. Se la routine di associazione restituisce semplicemente NULL, il codice client riceve un errore RPC_S_INVALID_BINDING. Anche se questo potrebbe essere accettabile in determinate situazioni, altre situazioni (ad esempio non sono in memoria) non rispondono correttamente. La routine non associazione deve essere progettata in modo che non riesca. La routine unbind non deve generare eccezioni.
Le routine di associazione e di associazione definite dal programmatore vengono visualizzate nell'applicazione client. Nell'esempio seguente la routine di associazione chiama RpcBindingFromStringBinding per convertire le informazioni sull'associazione di stringhe in un handle di associazione. La routine unbind chiama RpcBindingFree per liberare l'handle di associazione.
Il nome dell'handle di associazione definito dal programmatore, DATA_HANDLE_TYPE, viene visualizzato come parte del nome delle funzioni. Viene usato anche come tipo di parametro nei parametri della funzione.
/* The client stub calls this _bind routine at the */
/* beginning of each remote procedure call */
RPC_BINDING_HANDLE __RPC_USER DATA_HANDLE_TYPE_bind(
DATA_HANDLE_TYPE dh1)
{
RPC_BINDING_HANDLE hBinding;
RPC_STATUS status;
unsigned char *pszStringBinding;
status = RpcStringBindingCompose(
dh1.pszUuid,
dh1.pszProtocolSequence,
dh1.pszNetworkAddress,
dh1.pszEndpoint,
dh1.pszOptions,
&pszStringBinding);
...
status = RpcBindingFromStringBinding(
pszStringBinding,
&hBinding);
...
status = RpcStringFree(&pszStringBinding);
...
return(hBinding);
}
/* The client stub calls this _unbind routine */
/* after each remote procedure call. */
void __RPC_USER DATA_HANDLE_TYPE_unbind(
DATA_HANDLE_TYPE dh1,
RPC_BINDING_HANDLE h1)
{
RPC_STATUS status;
status = RpcBindingFree(&h1);
...
}
Entrambi gli handle di associazione impliciti ed espliciti possono essere handle primitivi o personalizzati. Ovvero, un handle può essere:
- Primitiva e implicita
- Personalizzato e implicito
- Primitiva ed esplicita
- Personalizzato ed esplicito