Udostępnij za pośrednictwem


Aplikacja kliencka

Poniższy przykład pochodzi z aplikacji "Hello World" w katalogu RPC\Hello zestawu Sdk platformy. Plik źródłowy Helloc.c zawiera dyrektywę zawierającą plik nagłówka wygenerowany przez MIDL, Hello.h. W pliku Hello.h znajdują się dyrektywy, które obejmują Rpc.h i rpcndr.h, które zawierają definicje procedur czasu wykonywania RPC, HelloProc i Shutdowni typów danych używanych przez aplikacje klienckie i serwerowe. Kompilator MIDL musi być używany z poniższym przykładem.

Ponieważ klient zarządza połączeniem z serwerem, aplikacja kliencka wywołuje funkcje czasu wykonywania, aby ustanowić dojście do serwera i zwolnić ten uchwyt po zakończeniu zdalnych wywołań procedur. Funkcja RpcStringBindingCompose łączy składniki uchwytu powiązania w reprezentację ciągu tego uchwytu i przydziela pamięć dla powiązania ciągu. Funkcja RpcBindingFromStringBinding tworzy dojście powiązania serwera, hello_ClientIfHandle, dla aplikacji klienckiej z tej reprezentacji ciągu.

W wywołaniu metody RpcStringBindingComposeparametry nie określają identyfikatora UUID, ponieważ w tym samouczku założono, że istnieje tylko jedna implementacja interfejsu "hello". Ponadto wywołanie nie określa adresu sieciowego, ponieważ aplikacja będzie używać wartości domyślnej, czyli lokalnej maszyny hosta. Sekwencja protokołu to ciąg znaków reprezentujący podstawowy transport sieciowy. Punkt końcowy to nazwa specyficzna dla sekwencji protokołów. W tym przykładzie użyto nazwanych potoków do transportu sieciowego, więc sekwencja protokołu to "ncacn_np". Nazwa punktu końcowego to "\pipe\hello".

Rzeczywiste wywołania procedury zdalnej, HelloProc i Shutdown, odbywają się w programie obsługi wyjątków RPC — zestawie makr, które pozwalają kontrolować wyjątki występujące poza kodem aplikacji. Jeśli moduł czasu wykonywania RPC zgłasza wyjątek, kontrolka przechodzi do bloku RpcExcept. W tym miejscu należy wstawić kod, aby wykonać wszelkie potrzebne czyszczenie, a następnie bezpiecznie zakończyć pracę. Ten przykładowy program po prostu informuje użytkownika o wystąpieniu wyjątku. Jeśli nie chcesz używać wyjątków, możesz użyć atrybutów usługi ACF comm_status i fault_status do zgłaszania błędów.

Po zakończeniu wywołań procedury zdalnej klient najpierw wywołuje RpcStringFree zwolnić pamięć przydzieloną do powiązania ciągu. Należy pamiętać, że po utworzeniu dojścia powiązania program kliencki może zwolnić powiązanie ciągu w dowolnym momencie. Następnie klient wywołuje RpcBindingFree, aby zwolnić dojście.

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