Know-how: Kommunikation mit Remote Procedure Calls

RPC-Client

Der Client muss zunächst die RPC-Verbindung spezifizieren. Er benutzt dazu die Funktion RpcStringBindingCompose, um aus einer Anzahl von Parametern eine Zeichenkette zu konstruieren. Abhängig vom Protokoll müssen nicht unbedingt alle Parameter gesetzt werden. So benötigt das Protokoll über named pipes keine Netzwerkadresse, da es nur zwischen Prozessen auf einem Rechner verwendet werden kann.

Diese Zeichenkette wird dann an RpcBindingFromStringBinding übergeben. Bei Erfolg ist das Interface aktiviert, und das zweite Argument enthält einen gültigen so genannten Handle auf das Interface. Danach kann der Client die Prozeduren aufrufen. Die Aufrufe sind im Beispiel in einen speziellen RpcTryExcept Block eingebettet, der eventuelle Laufzeitfehler auffängt.

Der Client ruft in diesem Beispiel 10-mal die Prozedur testKomm auf. Am Ende werden noch die belegten Ressourcen wieder freigegeben. Das Programm hat folgende Form:

/* file: telbuc.c */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "telbu.h"

void main()
{
RPC_STATUS status;
unsigned char *pszUuid = NULL;
unsigned char *pszProtocolSequence = "ncacn_ip_tcp";
unsigned char *pszNetworkAddress = "127.0.0.1";
unsigned char *pszEndpoint = "5432";
unsigned char *pszOptions = NULL;
unsigned char *pszStringBinding = NULL;
unsigned char *testString = "Hallo Server";
unsigned long ulCode;

status = RpcStringBindingCompose(pszUuid, pszProtocolSequence, pszNetworkAddress, pszEndpoint, pszOptions, &pszStringBinding);
if (status) exit(status);
printf("pszStringBinding: %s\\n", pszStringBinding );

status = RpcBindingFromStringBinding(pszStringBinding, &telbu_IfHandle);
if (status) exit(status);

RpcTryExcept {
int i;
// mehrfach die Test-Prozedur aufrufen
for( i=0; i&lt;10; i++ ) {
printf("%d ", i);
testKomm(testString);
Sleep( 1000 );
}
}
RpcExcept(1) {
ulCode = RpcExceptionCode();
printf("Runtime exception 0x%lx = %ld\\n", ulCode, ulCode);
}
RpcEndExcept

status = RpcStringFree(&pszStringBinding);
if (status) exit(status);

status = RpcBindingFree(&telbu_IfHandle);
if (status) exit(status);

exit(0);
} // end main()

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