Application cliente
L’exemple ci-dessous provient de l’application « Hello World » dans le répertoire RPC\Hello du Kit de développement logiciel (SDK) de plateforme. Le fichier source Helloc.c contient une directive pour inclure le fichier d’en-tête généré par MIDL, Hello.h. Dans Hello.h, sont des directives pour inclure Rpc.h et rpcndr.h, qui contiennent les définitions des routines d’exécution RPC, HelloProc et arrêteret les types de données utilisés par les applications clientes et serveurs. Le compilateur MIDL doit être utilisé avec l’exemple ci-dessous.
Étant donné que le client gère sa connexion au serveur, l’application cliente appelle des fonctions d’exécution pour établir un handle sur le serveur et libérer ce handle une fois les appels de procédure distante terminés. La fonction RpcStringBindingCompose combine les composants du handle de liaison en une représentation sous forme de chaîne de ce handle et alloue de la mémoire pour la liaison de chaîne. La fonction RpcBindingFromStringBinding crée un handle de liaison de serveur, hello_ClientIfHandle, pour l’application cliente à partir de cette représentation sous forme de chaîne.
Dans l’appel à RpcStringBindingCompose, les paramètres ne spécifient pas l’UUID, car ce didacticiel suppose qu’il n’existe qu’une seule implémentation de l’interface « hello ». En outre, l’appel ne spécifie pas d’adresse réseau, car l’application utilise la valeur par défaut, qui est l’ordinateur hôte local. La séquence de protocole est une chaîne de caractères qui représente le transport réseau sous-jacent. Le point de terminaison est un nom spécifique à la séquence de protocole. Cet exemple utilise des canaux nommés pour son transport réseau, de sorte que la séquence de protocole est « ncacn_np ». Le nom du point de terminaison est « \pipe\hello ».
Les appels de procédure distante réelle, HelloProc et arrêt, se produisent dans le gestionnaire d’exceptions RPC, un ensemble de macros qui vous permettent de contrôler les exceptions qui se produisent en dehors du code de l’application. Si le module d’exécution RPC signale une exception, le contrôle passe au blocRpcExcept. C’est là que vous inséreriez du code pour effectuer tout nettoyage nécessaire, puis quitter correctement. Cet exemple de programme informe simplement l’utilisateur qu’une exception s’est produite. Si vous ne souhaitez pas utiliser d’exceptions, vous pouvez utiliser les attributs ACF comm_status et fault_status pour signaler des erreurs.
Une fois les appels de procédure distante terminés, le client appelle d’abord RpcStringFree pour libérer la mémoire allouée pour la liaison de chaîne. Notez qu’une fois le handle de liaison créé, un programme client peut libérer une liaison de chaîne à tout moment. Le client appelle ensuite RpcBindingFree pour libérer le handle.
/* 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);
}