用戶端應用程式
下列範例來自平臺軟體發展工具組 (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的呼叫中,參數不會指定 UUID,因為本教學課程假設只有一個介面 「hello」 實作。此外,呼叫不會指定網路位址,因為應用程式會使用預設值,也就是本機主機電腦。 通訊協定序列是代表基礎網路傳輸的字元字串。 端點是通訊協定序列特有的名稱。 此範例會使用具名管道進行網路傳輸,因此通訊協定順序為 「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);
}