用戶端應用程式

下列範例來自平臺軟體發展工具組 (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);
}