Identificadores de enlace primitivos y personalizados
Todos los identificadores declarados con los tipos handle_t o RPC_BINDING_HANDLE son identificadores de enlace primitivos. Puede ampliar los tipos de handle_t o RPC_BINDING_HANDLE para incluir más o diferente información que el tipo de identificador primitivo contiene. Al hacerlo, se crea un identificador de enlace personalizado.
Para crear un identificador de enlace personalizado para la aplicación distribuida, deberá crear su propio tipo de datos y especificar el atributo [ handle] en una definición de tipo en el archivo IDL. En última instancia, los archivos de código auxiliar asignan identificadores de enlace personalizados a identificadores primitivos.
Si crea su propio tipo de identificador de enlace, también debe proporcionar rutinas de enlace y desenlace que usa el código auxiliar del cliente para asignar un identificador personalizado a un identificador primitivo. El código auxiliar llama a las rutinas de enlace y desenlace al principio y al final de cada llamada a procedimiento remoto. Las rutinas de enlace y desenlace deben cumplir los siguientes prototipos de función.
Prototipo de función | Descripción |
---|---|
handle_t type_bind(type) | Rutina de enlace |
void type_unbind(type, handle_t) | Rutina de desenlazamiento |
En el ejemplo siguiente se muestra cómo se puede definir un identificador de enlace personalizado en el archivo 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);
}
Si la rutina de enlace encuentra un error, debe generar una excepción mediante la función RpcRaiseException . A continuación, el código auxiliar del cliente se limpiará y permitirá que el filtro de excepciones pase al bloque de excepciones que rodea la llamada a procedimiento remoto en el lado cliente. Si la rutina de enlace simplemente devuelve NULL, el código de cliente obtiene el error RPC_S_INVALID_BINDING. Aunque esto puede ser aceptable en determinadas situaciones, otras situaciones (como estar fuera de memoria) no responden bien. La rutina de desenlace debe diseñarse para que no se produzca un error. La rutina de desenlace no debe generar excepciones.
Las rutinas de enlace y desenlace definidas por el programador aparecen en la aplicación cliente. En el ejemplo siguiente, la rutina de enlace llama a RpcBindingFromStringBinding para convertir la información de enlace de cadena en un identificador de enlace. La rutina unbind llama a RpcBindingFree para liberar el identificador de enlace.
El nombre del identificador de enlace definido por el programador, DATA_HANDLE_TYPE, aparece como parte del nombre de las funciones. También se usa como tipo de parámetro en los parámetros de función.
/* 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);
...
}
Los identificadores de enlace implícitos y explícitos pueden ser identificadores primitivos o personalizados. Es decir, un identificador puede ser:
- Primitivo e implícito
- Personalizado e implícito
- Primitivo y explícito
- Personalizado y explícito