Aplicación cliente
El ejemplo siguiente procede de la aplicación "Hola mundo" en el directorio RPC\Hello del Kit de desarrollo de software de plataforma (SDK). El archivo de origen Helloc.c contiene una directiva para incluir el archivo de encabezado generado por MIDL, Hello.h. Dentro de Hello.h hay directivas para incluir Rpc.h y rpcndr.h, que contienen las definiciones de las rutinas en tiempo de ejecución de RPC, HelloProc y Shutdown, y los tipos de datos que usan las aplicaciones cliente y servidor. El compilador MIDL debe usarse con el ejemplo siguiente.
Dado que el cliente administra su conexión con el servidor, la aplicación cliente llama a funciones en tiempo de ejecución para establecer un identificador para el servidor y liberar este identificador una vez completadas las llamadas a procedimiento remoto. La función RpcStringBindingCompose combina los componentes del identificador de enlace en una representación de cadena de ese identificador y asigna memoria para el enlace de cadena. La función RpcBindingFromStringBinding crea un identificador de enlace de servidor, hello_ClientIfHandle, para la aplicación cliente a partir de esa representación de cadena.
En la llamada a RpcStringBindingCompose, los parámetros no especifican el UUID porque en este tutorial se supone que solo hay una implementación de la interfaz "hello". Además, la llamada no especifica una dirección de red porque la aplicación usará el valor predeterminado, que es la máquina host local. La secuencia de protocolo es una cadena de caracteres que representa el transporte de red subyacente. El punto de conexión es un nombre específico de la secuencia de protocolos. En este ejemplo se usan canalizaciones con nombre para su transporte de red, por lo que la secuencia de protocolo es "ncacn_np". El nombre del punto de conexión es "\pipe\hello".
Las llamadas a procedimientos remotos reales, HelloProc y Shutdown, tienen lugar dentro del controlador de excepciones RPC, un conjunto de macros que permiten controlar las excepciones que se producen fuera del código de la aplicación. Si el módulo en tiempo de ejecución rpc notifica una excepción, el control pasa al bloque RpcExcept . Aquí es donde insertaría código para realizar cualquier limpieza necesaria y, a continuación, salir correctamente. Este programa de ejemplo simplemente informa al usuario de que se produjo una excepción. Si no desea usar excepciones, puede usar los atributos de ACF comm_status y fault_status para notificar errores.
Una vez completadas las llamadas a procedimiento remoto, el cliente llama primero a RpcStringFree para liberar la memoria que se asignó para el enlace de cadenas. Tenga en cuenta que una vez creado el identificador de enlace, un programa cliente puede liberar un enlace de cadena en cualquier momento. A continuación, el cliente llama a RpcBindingFree para liberar el identificador.
/* 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);
}