O aplicativo cliente
O exemplo abaixo é do aplicativo 'Hello World' no diretório RPC\Hello do Platform Software Development Kit (SDK). O arquivo de origem Helloc.c contém uma diretiva para incluir o arquivo de cabeçalho gerado por MIDL, Hello.h. Dentro de Hello.h estão diretivas para incluir Rpc.h e rpcndr.h, que contêm as definições para as rotinas de tempo de execução RPC, HelloProc e Shutdowne tipos de dados que os aplicativos cliente e servidor usam. O compilador MIDL deve ser usado com o exemplo abaixo.
Como o cliente está gerenciando sua conexão com o servidor, o aplicativo cliente chama funções de tempo de execução para estabelecer um identificador para o servidor e liberar esse identificador após a conclusão das chamadas de procedimento remoto. A função RpcStringBindingCompose combina os componentes do identificador de ligação em uma representação de cadeia de caracteres desse identificador e aloca memória para a associação de cadeia de caracteres. A função RpcBindingFromStringBinding cria um identificador de ligação de servidor, hello_ClientIfHandle, para o aplicativo cliente a partir dessa representação de cadeia de caracteres.
Na chamada para RpcStringBindingCompose, os parâmetros não especificam o UUID porque este tutorial pressupõe que há apenas uma implementação da interface "hello". Além disso, a chamada não especifica um endereço de rede porque o aplicativo usará o padrão, que é a máquina host local. A sequência de protocolo é uma cadeia de caracteres que representa o transporte de rede subjacente. O ponto de extremidade é um nome específico para a sequência de protocolo. Este exemplo usa pipes nomeados para seu transporte de rede, portanto, a sequência de protocolo é "ncacn_np". O nome do ponto de extremidade é "\pipe\hello".
As chamadas de procedimento remoto reais, HelloProc e Shutdown, ocorrem dentro do manipulador de exceções RPC — um conjunto de macros que permite controlar exceções que ocorrem fora do código do aplicativo. Se o módulo de tempo de execução RPC relatar uma exceção, o controle passará para o bloco RpcExcept. É aqui que você inseriria o código para fazer qualquer limpeza necessária e, em seguida, sair normalmente. Este programa de exemplo simplesmente informa ao usuário que ocorreu uma exceção. Se você não quiser usar exceções, poderá usar os atributos ACF comm_status e fault_status para relatar erros.
Depois que as chamadas de procedimento remoto são concluídas, o cliente primeiro chama RpcStringFree para liberar a memória que foi alocada para a associação de cadeia de caracteres. Observe que, uma vez que o identificador de vinculação tenha sido criado, um programa cliente pode liberar uma vinculação de cadeia de caracteres a qualquer momento. Em seguida, o cliente chama RpcBindingFree para liberar o 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);
}