Delen via


De clienttoepassing

Het onderstaande voorbeeld is afkomstig uit de toepassing 'Hallo wereld' in de map RPC\Hello van de Platform Software Development Kit (SDK). Het Bronbestand Helloc.c bevat een instructie voor het door MIDL gegenereerde headerbestand Hello.h. Binnen Hello.h zijn instructies voor het opnemen van Rpc.h en rpcndr.h, die de definities voor de RPC-runtimeroutines bevatten, HelloProc- en Afsluiten, en gegevenstypen die de client- en servertoepassingen gebruiken. De MIDL-compiler moet worden gebruikt met het onderstaande voorbeeld.

Omdat de client de verbinding met de server beheert, roept de clienttoepassing runtimefuncties aan om een ingang tot stand te brengen voor de server en om deze ingang vrij te geven nadat de externe procedureaanroepen zijn voltooid. De functie RpcStringBindingCompose combineert de onderdelen van de bindingsgreep in een tekenreeksweergave van die ingang en wijst geheugen toe voor de tekenreeksbinding. De functie RpcBindingFromStringBinding maakt een serverbindingsgreep, hello_ClientIfHandle, voor de clienttoepassing uit die tekenreeksweergave.

In de aanroep naar RpcStringBindingCompose, geven de parameters de UUID niet op, omdat in deze zelfstudie wordt ervan uitgegaan dat er slechts één implementatie van de interface 'hallo' is. Bovendien geeft de aanroep geen netwerkadres op, omdat de toepassing de standaardwaarde gebruikt. Dit is de lokale hostcomputer. De protocolreeks is een tekenreeks die het onderliggende netwerktransport vertegenwoordigt. Het eindpunt is een naam die specifiek is voor de protocolreeks. In dit voorbeeld worden benoemde pijpen gebruikt voor het netwerktransport, dus de protocolreeks is 'ncacn_np'. De naam van het eindpunt is '\pipe\hello'.

De werkelijke aanroepen van externe procedures, HelloProc- en afsluiten, vinden plaats in de RPC-uitzonderingshandler, een set macro's waarmee u uitzonderingen kunt beheren die buiten de toepassingscode optreden. Als de RPC-runtimemodule een uitzondering rapporteert, wordt het besturingselement doorgegeven aan het RpcExcept blok. Hier kunt u code invoegen om eventueel opschonen uit te voeren en vervolgens probleemloos af te sluiten. Dit voorbeeldprogramma informeert de gebruiker gewoon dat er een uitzondering is opgetreden. Als u geen uitzonderingen wilt gebruiken, kunt u de ACF-kenmerken comm_status en fault_status gebruiken om fouten te rapporteren.

Nadat de externe procedureaanroepen zijn voltooid, roept de client eerst RpcStringFree om het geheugen vrij te maken dat is toegewezen voor de tekenreeksbinding. Zodra de bindingsgreep is gemaakt, kan een clientprogramma op elk gewenst moment een tekenreeksbinding vrijmaken. De client roept vervolgens RpcBindingFree aan om de ingang vrij te geven.

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