Freigeben über


Die Clientanwendung

Das folgende Beispiel stammt aus der Anwendung "Hallo Welt" im Verzeichnis RPC\Hello des Platform Software Development Kit (SDK). Die Quelldatei Helloc.c enthält eine Anweisung zum Einschließen der von MIDL generierten Headerdatei Hello.h. In Hello.h sind Anweisungen zum Einschließen von Rpc.h und rpcndr.h enthalten, die die Definitionen für die RPC-Laufzeitroutinen, HelloProc und Shutdown sowie datentypen enthalten, die die Client- und Serveranwendungen verwenden. Der MIDL-Compiler muss mit dem folgenden Beispiel verwendet werden.

Da der Client seine Verbindung mit dem Server verwaltet, ruft die Clientanwendung Laufzeitfunktionen auf, um ein Handle für den Server einzurichten und dieses Handle nach Abschluss der Remoteprozeduraufrufe freizugeben. Die Funktion RpcStringBindingCompose kombiniert die Komponenten des Bindungshandles in einer Zeichenfolgendarstellung dieses Handles und weist Arbeitsspeicher für die Zeichenfolgenbindung zu. Die Funktion RpcBindingFromStringBinding erstellt ein Serverbindungshandle hello_ClientIfHandle für die Clientanwendung aus dieser Zeichenfolgendarstellung.

Beim Aufruf von RpcStringBindingCompose geben die Parameter die UUID nicht an, da in diesem Tutorial davon ausgegangen wird, dass es nur eine Implementierung der Schnittstelle "hello" gibt. Darüber hinaus gibt der Aufruf keine Netzwerkadresse an, da die Anwendung den Standardwert verwendet, d. h. den lokalen Hostcomputer. Die Protokollsequenz ist eine Zeichenfolge, die den zugrunde liegenden Netzwerktransport darstellt. Der Endpunkt ist ein Name, der für die Protokollsequenz spezifisch ist. In diesem Beispiel werden Named Pipes für den Netzwerktransport verwendet, sodass die Protokollsequenz "ncacn_np" lautet. Der Endpunktname lautet "\pipe\hello".

Die eigentlichen Remoteprozeduraufrufe HelloProc und Shutdown finden innerhalb des RPC-Ausnahmehandlers statt– einer Gruppe von Makros, mit denen Sie Ausnahmen steuern können, die außerhalb des Anwendungscodes auftreten. Wenn das RPC-Laufzeitmodul eine Ausnahme meldet, wird das Steuerelement an den RpcExcept-Block übergeben. Hier würden Sie Code einfügen, um alle erforderlichen Bereinigungen zu erledigen und dann ordnungsgemäß zu beenden. Dieses Beispielprogramm informiert den Benutzer einfach darüber, dass eine Ausnahme aufgetreten ist. Wenn Sie keine Ausnahmen verwenden möchten, können Sie die ACF-Attribute comm_status und fault_status verwenden, um Fehler zu melden.

Nachdem die Remoteprozeduraufrufe abgeschlossen sind, ruft der Client zuerst RpcStringFree auf, um den Arbeitsspeicher freizugeben, der für die Zeichenfolgenbindung zugewiesen wurde. Beachten Sie, dass nach dem Erstellen des Bindungshandles ein Clientprogramm eine Zeichenfolgenbindung jederzeit freigeben kann. Der Client ruft als Nächstes RpcBindingFree auf, um das Handle freizugeben.

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