Identificadores de associação primitivos e personalizados

Todos os identificadores declarados com os tipos handle_t ou RPC_BINDING_HANDLE são identificadores de associação primitivos. Você pode estender os tipos de handle_t ou RPC_BINDING_HANDLE para incluir mais informações ou informações diferentes do tipo de identificador primitivo que contém. Ao fazer isso, você cria um identificador de associação personalizado.

Para criar um identificador de associação personalizado para seu aplicativo distribuído, você precisará criar seu próprio tipo de dados e especificar o atributo [ handle] em uma definição de tipo em seu arquivo IDL. Por fim, os arquivos stub mapeiam identificadores de associação personalizados para identificadores primitivos.

Se você criar seu próprio tipo de identificador de associação, também deverá fornecer rotinas de associação e desassociadas que o stub do cliente usa para mapear um identificador personalizado para um identificador primitivo. O stub chama suas rotinas de associação e desassociadas no início e no final de cada chamada de procedimento remoto. As rotinas de associação e desassociação devem estar em conformidade com os protótipos de função a seguir.

Protótipo da função Descrição
handle_t type_bind(type) Rotina de associação
void type_unbind(type, handle_t) Rotina de desassociação

 

O exemplo a seguir mostra como um identificador de associação personalizado pode ser definido no arquivo 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 a rotina de associação encontrar um erro, ela deverá gerar uma exceção usando a função RpcRaiseException . Em seguida, o stub do cliente limpo e deixará a exceção filtrar até o bloco de exceção em torno da chamada de procedimento remoto no lado do cliente. Se a rotina de associação simplesmente retornar NULL, o código do cliente receberá um erro RPC_S_INVALID_BINDING. Embora isso possa ser aceitável em determinadas situações, outras situações (como ficar sem memória) não respondem bem. A rotina desassociada deve ser projetada para que não falhe. A rotina desassociada não deve gerar exceções.

As rotinas de associação e desassociação definidas pelo programador aparecem no aplicativo cliente. No exemplo a seguir, a rotina de associação chama RpcBindingFromStringBinding para converter as informações de associação de cadeia de caracteres em um identificador de associação. A rotina desassociada chama RpcBindingFree para liberar o identificador de associação.

O nome do identificador de associação definido pelo programador, DATA_HANDLE_TYPE, aparece como parte do nome das funções. Ele também é usado como o tipo de parâmetro nos parâmetros de função.

/* 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); 
    ...
}

Os identificadores de associação implícita e explícita podem ser identificadores primitivos ou personalizados. Ou seja, um identificador pode ser:

  • Primitivo e implícito
  • Personalizado e implícito
  • Primitivo e explícito
  • Personalizado e explícito