Die Clientanwendung
Das folgende Beispiel stammt aus der Anwendung "Hello World" im Verzeichnis "RPC\Hello" des Platform Software Development Kit (SDK). Die Helloc.c-Quelldatei enthält eine Direktive, um die von MIDL generierte Headerdatei "Hello.h" einzuschließen. In Hello.h sind Direktiven enthalten rpc.h und rpcndr.h, die die Definitionen für die RPC-Laufzeitroutinen, HelloProc- und Herunterfahrensowie Datentypen enthalten, die von den Client- und Serveranwendungen verwendet werden. 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 Bindungshandle in einer Zeichenfolgendarstellung dieses Handles und weist Speicher für die Zeichenfolgenbindung zu. Die Funktion RpcBindingFromStringBinding erstellt ein Serverbindungshandle hello_ClientIfHandlefür die Clientanwendung aus dieser Zeichenfolgendarstellung.
Im Aufruf von RpcStringBindingCompose-geben die Parameter nicht die UUID an, da in diesem Lernprogramm davon ausgegangen wird, dass nur eine Implementierung der Schnittstelle "hello" vorhanden ist. Darüber hinaus gibt der Aufruf keine Netzwerkadresse an, da die Anwendung den Standardwert verwendet, bei dem es sich um den lokalen Hostcomputer handelt. 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 benannte Rohre für den Netzwerktransport verwendet, sodass die Protokollsequenz "ncacn_np" lautet. Der Endpunktname lautet "\pipe\hello".
Die tatsächlichen Remoteprozeduraufrufe, HelloProc- und Herunterfahren, finden innerhalb des RPC-Ausnahmehandlers statt – eine Reihe 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 wurden, ruft der Client zuerst RpcStringFree- auf, um den Speicher freizugeben, der für die Zeichenfolgenbindung zugewiesen wurde. Beachten Sie, dass ein Clientprogramm, nachdem das Bindungshandle erstellt wurde, jederzeit eine Zeichenfolgenbindung 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);
}