O aplicativo cliente
O exemplo a seguir é do aplicativo 'Olá, Mundo' no diretório RPC\Hello do SDK (Platform Software Development Kit). O arquivo de origem Helloc.c contém uma diretiva para incluir o arquivo de cabeçalho gerado por MIDL, Hello.h. No Hello.h há 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 Shutdown e 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 em 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 associaçã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 associação de servidor, hello_ClientIfHandle, para o aplicativo cliente dessa representação de cadeia de caracteres.
Na chamada para RpcStringBindingCompose, os parâmetros não especificam a 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 é o computador 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ção RPC— um conjunto de macros que permitem 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ê insere o código para fazer qualquer limpeza necessária e 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 forem concluídas, o cliente primeiro chamará RpcStringFree para liberar a memória alocada para a associação de cadeia de caracteres. Observe que, depois que o identificador de associação for criado, um programa cliente poderá liberar uma associaçã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);
}