用戶端應用程式
下列範例來自平臺軟體開發工具包 (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);
}