クライアント アプリケーション
次の例は、プラットフォーム ソフトウェア開発キット (SDK) の RPC\Hello ディレクトリにある "Hello World" アプリケーションの例です。 Helloc.c ソース ファイルには、MIDL で生成されたヘッダー ファイル Hello.h を含む ディレクティブが含まれています。 Hello.h 内には、Rpc.h と rpcndr.h を含めるディレクティブがあります。これには、RPC ランタイム ルーチン、 HelloProc と Shutdown、およびクライアントおよびサーバー アプリケーションで使用されるデータ型の定義が含まれます。 MIDL コンパイラは、次の例と共に使用する必要があります。
クライアントはサーバーへの接続を管理しているため、クライアント アプリケーションはランタイム関数を呼び出してサーバーへのハンドルを確立し、リモート プロシージャ呼び出しが完了した後にこのハンドルを解放します。 関数 RpcStringBindingCompose は、バインド ハンドルのコンポーネントを、そのハンドルの文字列表現に結合し、文字列バインディングにメモリを割り当てます。 関数 RpcBindingFromStringBinding は、その文字列表現からクライアント アプリケーションのサーバー バインド ハンドル (hello_ClientIfHandle) を作成します。
RpcStringBindingCompose の呼び出しでは、このチュートリアルではインターフェイス "hello" の実装が 1 つだけであることを前提としているため、パラメーターで UUID は指定されません。また、アプリケーションではローカル ホスト コンピューターである既定値が使用されるため、呼び出しではネットワーク アドレスは指定されません。 プロトコル シーケンスは、基になるネットワーク トランスポートを表す文字列です。 エンドポイントは、プロトコル シーケンスに固有の名前です。 この例では、名前付きパイプをネットワーク トランスポートに使用するため、プロトコル シーケンスは "ncacn_np" です。 エンドポイント名は "\pipe\hello" です。
実際のリモート プロシージャ 呼び出し HelloProc と Shutdown は、RPC 例外ハンドラー内で実行されます。これは、アプリケーション コードの外部で発生する例外を制御できるマクロのセットです。 RPC ランタイム モジュールが例外を報告した場合、コントロールは RpcExcept ブロックに渡されます。 ここで、必要なクリーンアップを行い、正常に終了するコードを挿入します。 このプログラム例では、例外が発生したことをユーザーに通知するだけです。 例外を使用しない場合は、ACF 属性 comm_status と fault_status を使用してエラーを報告できます。
リモート プロシージャ呼び出しが完了すると、クライアントは最初に RpcStringFree を呼び出して、文字列バインディングに割り当てられたメモリを解放します。 バインド ハンドルが作成されると、クライアント プログラムは文字列バインディングをいつでも解放できることに注意してください。 クライアントは次に RpcBindingFree を 呼び出してハンドルを解放します。
/* file: helloc.c */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "hello.h"
#include <windows.h>
void main()
{
RPC_STATUS status;
unsigned char * pszUuid = NULL;
unsigned char * pszProtocolSequence = "ncacn_np";
unsigned char * pszNetworkAddress = NULL;
unsigned char * pszEndpoint = "\\pipe\\hello";
unsigned char * pszOptions = NULL;
unsigned char * pszStringBinding = NULL;
unsigned char * pszString = "hello, world";
unsigned long ulCode;
status = RpcStringBindingCompose(pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszStringBinding);
if (status) exit(status);
status = RpcBindingFromStringBinding(pszStringBinding, &hello_ClientIfHandle);
if (status) exit(status);
RpcTryExcept
{
HelloProc(pszString);
Shutdown();
}
RpcExcept(1)
{
ulCode = RpcExceptionCode();
printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
}
RpcEndExcept
status = RpcStringFree(&pszStringBinding);
if (status) exit(status);
status = RpcBindingFree(&hello_IfHandle);
if (status) exit(status);
exit(0);
}
/******************************************************/
/* MIDL allocate and free */
/******************************************************/
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}