Poignées de liaison primitives et personnalisées

Tous les handles déclarés avec les types handle_t ou RPC_BINDING_HANDLE sont des handles de liaison primitifs. Vous pouvez étendre les types handle_t ou RPC_BINDING_HANDLE pour inclure des informations plus ou différentes que celles du type de handle primitif. Dans ce cas, vous créez un handle de liaison personnalisé.

Pour créer un handle de liaison personnalisé pour votre application distribuée, vous devez créer votre propre type de données et spécifier l’attribut [ handle] sur une définition de type dans votre fichier IDL. En fin de compte, les fichiers stub mappent les handles de liaison personnalisés aux handles primitifs.

Si vous créez votre propre type de handle de liaison, vous devez également fournir des routines de liaison et de dissociée que le stub client utilise pour mapper un handle personnalisé à un handle primitif. Le stub appelle vos routines de liaison et de dissociation au début et à la fin de chaque appel de procédure distante. Les routines de liaison et de dissociation doivent être conformes aux prototypes de fonction suivants.

Prototype de fonction Description
handle_t type_bind(type) Routine de liaison
void type_unbind(type, handle_t) Annuler la liaison de la routine

 

L’exemple suivant montre comment un handle de liaison personnalisé peut être défini dans le fichier 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 routine de liaison rencontre une erreur, elle doit déclencher une exception à l’aide de la fonction RpcRaiseException . Le stub client propre et laisse l’exception filtrer jusqu’au bloc d’exception entourant l’appel de procédure distante côté client. Si la routine de liaison retourne simplement NULL, le code client obtient une erreur RPC_S_INVALID_BINDING. Bien que cela puisse être acceptable dans certaines situations, d’autres situations (telles que la mémoire insuffisante) ne répondent pas correctement. La routine dissociée doit être conçue de sorte qu’elle n’échoue pas. La routine unbind ne doit pas déclencher d’exceptions.

Les routines de liaison et d’annulation définies par le programmeur apparaissent dans l’application cliente. Dans l’exemple suivant, la routine de liaison appelle RpcBindingFromStringBinding pour convertir les informations de liaison de chaîne en handle de liaison. La routine de dissociation appelle RpcBindingFree pour libérer le handle de liaison.

Le nom du handle de liaison défini par le programmeur, DATA_HANDLE_TYPE, apparaît dans le nom des fonctions. Il est également utilisé comme type de paramètre dans les paramètres de fonction.

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

Les handles de liaison implicites et explicites peuvent être des handles primitifs ou personnalisés. Autrement dit, un handle peut être :

  • Primitive et implicite
  • Personnalisé et implicite
  • Primitive et explicite
  • Personnalisé et explicite