다음을 통해 공유


클라이언트 애플리케이션

아래 예제는 SDK(플랫폼 소프트웨어 개발 키트)의 RPC\Hello 디렉터리에 있는 '헬로 월드' 애플리케이션에서 가져옵니다. Helloc.c 원본 파일에는 MIDL 생성 헤더 파일 Hello.h를 포함하는 지시문이 포함되어 있습니다. Hello.h 내에는 RPC 런타임 루틴, HelloProcShutdown에 대한 정의와 클라이언트 및 서버 애플리케이션에서 사용하는 데이터 형식이 포함된 Rpc.h 및 rpcndr.h를 포함하는 지시문이 있습니다. MIDL 컴파일러는 아래 예제와 함께 사용해야 합니다.

클라이언트가 서버에 대한 연결을 관리하기 때문에 클라이언트 애플리케이션은 런타임 함수를 호출하여 서버에 대한 핸들을 설정하고 원격 프로시저 호출이 완료된 후 이 핸들을 해제합니다. RpcStringBindingCompose 함수는 바인딩 핸들의 구성 요소를 해당 핸들의 문자열 표현으로 결합하고 문자열 바인딩에 대한 메모리를 할당합니다. RpcBindingFromStringBinding 함수는 해당 문자열 표현의 클라이언트 애플리케이션에 대해 hello_ClientIfHandle 서버 바인딩 핸들을 만듭니다.

RpcStringBindingCompose 호출에서 매개 변수는 UUID를 지정하지 않습니다. 이 자습서에서는 인터페이스 "hello"의 구현이 하나만 있다고 가정하기 때문입니다. 또한 애플리케이션은 로컬 호스트 컴퓨터인 기본값을 사용하기 때문에 호출에서 네트워크 주소를 지정하지 않습니다. 프로토콜 시퀀스는 기본 네트워크 전송을 나타내는 문자열입니다. 엔드포인트는 프로토콜 시퀀스에 특정한 이름입니다. 이 예제에서는 네트워크 전송에 명명된 파이프를 사용하므로 프로토콜 시퀀스는 "ncacn_np"입니다. 엔드포인트 이름은 "\pipe\hello"입니다.

실제 원격 프로시저 호출인 HelloProcShutdown은 애플리케이션 코드 외부에서 발생하는 예외를 제어할 수 있는 매크로 집합인 RPC 예외 처리기 내에서 수행됩니다. RPC 런타임 모듈에서 예외를 보고하면 컨트롤이 RpcExcept 블록으로 전달됩니다. 여기서 필요한 정리를 수행하는 코드를 삽입한 다음 정상적으로 종료합니다. 이 예제 프로그램은 사용자에게 예외가 발생했음을 알릴 뿐입니다. 예외를 사용하지 않으려면 ACF 특성 comm_statusfault_status 사용하여 오류를 보고할 수 있습니다.

원격 프로시저 호출이 완료되면 클라이언트는 먼저 RpcStringFree를 호출하여 문자열 바인딩에 할당된 메모리를 해제합니다. 바인딩 핸들이 만들어지면 클라이언트 프로그램은 언제든지 문자열 바인딩을 해제할 수 있습니다. 클라이언트는 다음으로 RpcBindingFree를 호출하여 핸들을 해제합니다.

/* 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);
}