共用方式為


用戶端應用程式

下列範例來自平臺軟體開發工具包 (SDK) 之 RPC\Hello 目錄中的 'Hello World' 應用程式。 Helloc.c 原始程式檔包含 指示詞,以包含 MIDL 產生的頭檔 Hello.h。 在 Hello.h 中是包含 Rpc.h 和 rpcndr.h 的指示詞,其中包含 RPC 運行時間例程的定義、HelloProcShutdown,以及用戶端應用程式所使用的數據類型。 MIDL 編譯程式必須與下列範例搭配使用。

由於用戶端正在管理其與伺服器的連線,用戶端應用程式會呼叫運行時間函式來建立伺服器的句柄,並在遠端過程調用完成之後釋放此句柄。 函式 RpcStringBindingCompose 會將系結句柄的元件合併成該句柄的字串表示,併為字元串系結配置記憶體。 函式 RpcBindingFromStringBinding 會從該字串表示法建立用戶端應用程式的伺服器系結句柄 hello_ClientIfHandle

在呼叫 RpcStringBindingCompose中,參數不會指定 UUID,因為本教學課程假設只有一個介面 “hello” 的實作。此外,呼叫不會指定網路位址,因為應用程式會使用預設值,也就是本機主計算機。 通訊協定序列是代表基礎網路傳輸的字元字串。 端點是通訊協定序列特有的名稱。 此範例會使用命名管道進行網路傳輸,因此通訊協定順序為「ncacn_np」。 端點名稱為 “\pipe\hello”。

實際的遠端過程調用 HelloProcShutdown,會在 RPC 例外狀況處理程式內進行,這是一組巨集,可讓您控制在應用程式程式代碼外部發生的例外狀況。 如果 RPC 執行時間模組報告例外狀況,控件會傳遞至 RpcExcept 區塊。 這是您要插入程式代碼以執行任何必要的清除,然後正常結束的位置。 此範例程式只會通知用戶發生例外狀況。 如果您不想使用例外狀況,您可以使用 ACF 屬性 comm_statusfault_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);
}