Primitive und benutzerdefinierte Bindungshandles

Alle Handles, die mit dem Handle _ t- oder RPC BINDING _ _ HANDLE-Typ deklariert werden, sind primitive Bindungshandles. Sie können die _ Handletypen t oder RPC BINDING _ _ HANDLE so erweitern, dass sie mehr oder andere Informationen enthalten, als der primitive Handletyp enthält. Wenn Sie dies tun, erstellen Sie ein benutzerdefiniertes Bindungshand handle.

Um ein benutzerdefiniertes Bindungshandl für Ihre verteilte Anwendung zu erstellen, müssen Sie einen eigenen Datentyp erstellen und das Handleattribut für eine Typdefinition in Ihrer [ ] IDL-Datei angeben. Letztendlich ordnen die Stubdateien benutzerdefinierte Bindungshandles primitiven Handles zu.

Wenn Sie einen eigenen Bindungshandpunkttyp erstellen, müssen Sie auch Bindungs- und Bindungsaufbindungsroutinen verwenden, die der Clientstub verwendet, um einem primitiven Handle ein benutzerdefiniertes Handle zu zuordnen. Der Stub ruft die Bindungs- und Bindungsroutinen am Anfang und Ende jedes Remoteprozeduraufrufs auf. Die Bindungs- und Bindungsaufbindungsroutinen müssen den folgenden Funktionsprototypen entsprechen.

Funktionsprototyp BESCHREIBUNG
handle _ t type _ bind(type) Bindungsroutine
void type _ unbind(type, handle _ t) Entbindungsroutine

Das folgende Beispiel zeigt, wie ein benutzerdefiniertes Bindungshandl in der IDL-Datei definiert werden kann:

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

Wenn die Bindungsroutine auf einen Fehler stößt, sollte sie mithilfe der RpcRerklärexception-Funktion eine Ausnahme auslösen. Der Clientstub wird dann bereinigt und lässt die Ausnahme bis zum Ausnahmeblock filtern, der den Remoteprozeduraufruf auf clientseitiger Seite umhing. Wenn die Bindungsroutine einfach NULL zurückgibt, erhält der Clientcode den Fehler RPC _ S INVALID _ _ BINDING. Dies kann in bestimmten Situationen akzeptabel sein, aber andere Situationen (z. B. nicht genügend Arbeitsspeicher) reagieren nicht gut. Die Unbind-Routine sollte so entworfen werden, dass sie nicht fehlschlägt. Die Unbind-Routine sollte keine Ausnahmen auslösen.

Die vom Programmierer definierten Bindungs- und Bindungsaufbindungsroutinen werden in der Clientanwendung angezeigt. Im folgenden Beispiel ruft die Bindungsroutine RpcBindingFromStringBinding auf, um die Zeichenfolgenbindungsinformationen in ein Bindungshand handle zu konvertieren. Die Unbind-Routine ruft RpcBindingFree auf, um das Bindungshand handle frei zu geben.

Der Name des vom Programmierer definierten Bindungshandrs DATA HANDLE TYPE wird als Teil des _ _ Namens der Funktionen angezeigt. Sie wird auch als Parametertyp in den Funktionsparametern verwendet.

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

Sowohl implizite als auch explizite Bindungshandles können primitive oder benutzerdefinierte Handles sein. Das heißt, ein Handle kann folgendes sein:

  • Primitiv und implizit
  • Benutzerdefiniert und implizit
  • Primitiv und explizit
  • Benutzerdefiniert und explizit