次の方法で共有


プリミティブ バインド ハンドルとカスタム バインド ハンドル

handle_t型またはRPC_BINDING_HANDLE型で宣言されたすべてのハンドルは、プリミティブ バインド ハンドルです。 handle_t型またはRPC_BINDING_HANDLE型を拡張して、プリミティブ ハンドル型に含まれる情報とは異なる情報を含めることができます。 その場合は、カスタム バインド ハンドルを作成します。

分散アプリケーションのカスタム バインド ハンドルを作成するには、独自のデータ型を作成し、IDL ファイルの型定義に [ handle] 属性を指定する必要があります。 最終的に、スタブ ファイルはカスタム バインド ハンドルをプリミティブ ハンドルにマップします。

独自のバインド ハンドル型を作成する場合は、クライアント スタブがカスタム ハンドルをプリミティブ ハンドルにマップするために使用するバインド ルーチンとバインド解除ルーチンも指定する必要があります。 スタブは、各リモート プロシージャ 呼び出しの先頭と末尾でバインド ルーチンとバインド解除ルーチンを呼び出します。 バインド ルーチンとバインド解除ルーチンは、次の関数プロトタイプに準拠している必要があります。

関数プロトタイプ 説明
handle_t type_bind() バインディング ルーチン
void type_unbind(type, handle_t) バインド解除ルーチン

 

次の例は、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);
}

バインド ルーチンでエラーが発生した場合は、 RpcRaiseException 関数を使用して例外を発生させる必要があります。 その後、クライアント スタブがクリーンし、例外がクライアント側のリモート プロシージャ 呼び出しを囲む例外ブロックにフィルター処理されます。 バインド ルーチンが 単に NULL を返す場合、クライアント コードはエラー RPC_S_INVALID_BINDINGを取得します。 これは特定の状況では許容される可能性があります。他の状況 (メモリ不足など) は適切に応答しません。 バインド解除ルーチンは、失敗しないように設計する必要があります。 バインド解除ルーチンは例外を発生させてはなりません。

プログラマ定義のバインドルーチンとバインド解除ルーチンは、クライアント アプリケーションに表示されます。 次の例では、バインド ルーチンは RpcBindingFromStringBinding を 呼び出して、文字列バインディング情報をバインド ハンドルに変換します。 バインド解除ルーチンは 、RpcBindingFree を呼び出してバインド ハンドルを解放します。

プログラマ定義のバインド ハンドルの名前 (DATA_HANDLE_TYPE) は、関数の名前の一部として表示されます。 これは、関数パラメーターのパラメーター型としても使用されます。

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

暗黙的なバインド ハンドルと明示的なバインド ハンドルの両方に、プリミティブ ハンドルまたはカスタム ハンドルを指定できます。 つまり、ハンドルは次のようになります。

  • プリミティブと暗黙的
  • カスタムと暗黙的
  • プリミティブと明示的
  • カスタムと明示的