Az ügyfélalkalmazás
Az alábbi példa a Platform Software Development Kit (SDK) RPC\Hello könyvtárában található "Hello World" alkalmazásból származik. A Helloc.c forrásfájl tartalmaz egy irányelvet, amely tartalmazza a MIDL által létrehozott fejlécfájlt, a Hello.h-t. A Hello.h-n belül az Rpc.h és az rpcndr.h irányelveket kell tartalmaznia, amelyek tartalmazzák az RPC futásidejű rutinok definícióit, a HelloProc és Leállítási, valamint az ügyfél- és kiszolgálóalkalmazások által használt adattípusokat. A MIDL-fordítót az alábbi példával kell használni.
Mivel az ügyfél kezeli a kiszolgálóhoz való kapcsolatot, az ügyfélalkalmazás futásidejű függvényeket hív meg, hogy hozzon létre egy leírót a kiszolgálóhoz, és engedje fel ezt a leírót a távoli eljáráshívások befejezése után. A függvény RpcStringBindingCompose egyesíti a kötési leíró összetevőit a leíró sztring-ábrázolásával, és memóriát foglal le a sztringkötéshez. A függvény RpcBindingFromStringBinding létrehoz egy kiszolgálókötési leírót, hello_ClientIfHandleaz ügyfélalkalmazás számára az adott sztring-ábrázolásból.
Az RpcStringBindingComposehívásában a paraméterek nem adják meg az UUID azonosítót, mivel ez az oktatóanyag feltételezi, hogy a felületnek csak egy implementációja van: "hello". Emellett a hívás nem ad meg hálózati címet, mert az alkalmazás az alapértelmezettet fogja használni, amely a helyi gazdagép. A protokollütemezés egy karaktersztring, amely a mögöttes hálózati átvitelt jelöli. A végpont a protokollütemezésre jellemző név. Ez a példa nevesített csöveket használ a hálózati átvitelhez, így a protokollütemezés "ncacn_np". A végpont neve "\pipe\hello".
A tényleges távoli eljáráshívások ( HelloProc és Leállítási) az RPC kivételkezelőn belül történnek– ez olyan makrókészlet, amely lehetővé teszi az alkalmazáskódon kívüli kivételek szabályozását. Ha az RPC futásidejű modul kivételt jelent, a vezérlő a RpcExcept blokkba kerül. Itt szúrhat be kódot, hogy elvégezhesse a szükséges tisztítást, majd elegánsan lépjen ki. Ez a példaprogram egyszerűen tájékoztatja a felhasználót, hogy kivétel történt. Ha nem szeretne kivételeket használni, az ACF attribútumokat comm_status és fault_status használhatja a hibák jelentéséhez.
A távoli eljáráshívások befejezése után az ügyfél először meghívja RpcStringFree, hogy felszabadítsa a sztringkötéshez lefoglalt memóriát. Vegye figyelembe, hogy a kötéskezelő létrehozása után az ügyfélprogram bármikor felszabadíthat egy sztringkötést. Az ügyfél ezután meghívja RpcBindingFree a leíró felszabadításához.
/* 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);
}