User-Defined Handles

A user-defined handle, also called a customized or generic handle, is a handle of a user-defined data type. You create a user-defined handle when you specify the handle attribute on a type definition in your IDL file.

You must also supply bind and unbind routines that the client stub calls at the beginning and end of each remote procedure call. The bind and unbind routines use the following function prototypes:

Function prototype Description
handle_t type_bind(type) Binding routine
void type_unbind(type, handle_t) Unbinding routine

The following example shows how the user-defined handle is defined in the IDL file:

/* usrdef.idl */
[uuid(20B309B1-015C-101A-B308-02608C4C9B53),
version(1.0),
pointer_default(unique)
]
interface usrdef
{
typedef struct _DATA_TYPE {
    unsigned char * pszUuid;
    unsigned char * pszProtocolSequence;
    unsigned char * pszNetworkAddress;
    unsigned char * pszEndpoint;
    unsigned char * pszOptions;
} DATA_TYPE;

typedef [handle] DATA_TYPE * DATA_HANDLE_TYPE;
void UsrdefProc(
                [in] DATA_HANDLE_TYPE  hBinding,
                [in, string] unsigned char *   pszString);

void Shutdown([in] DATA_HANDLE_TYPE hBinding);
}
 

The user-defined bind and unbind routines appear in the client application. In the following example, the bind routine converts the string-binding information to a binding handle by calling RpcBindingFromStringBinding. The unbind routine frees the binding handle by calling RpcBindingFree.

The name of the user-defined binding handle, DATA_HANDLE_TYPE, appears as part of the name of the functions and appears as the parameter type in the function parameters as:

/* This _bind routine is called by the client stub at the */
/* beginning of each remote procedure call                */

RPC_BINDING_HANDLE __RPC_USER DATA_HANDLE_TYPE_bind(DATA_HANDLE_TYPE dh1)
{
    RPC_BINDING_HANDLE hBinding;
    RPC_STATUS status;

unsigned char *pszStringBinding;

    status = RpcStringBindingCompose(
          dh1.pszUuid,
          dh1.pszProtocolSequence,
          dh1.pszNetworkAddress,
          dh1.pszEndpoint,
          dh1.pszOptions,
          &pszStringBinding);
          ...

    status = RpcBindingFromStringBinding(
          pszStringBinding,
          &hBinding);
          ...

    status = RpcStringFree(&pszStringBinding); 
    ...

    return(hBinding);
}

/* This _unbind routine is called by the client stub at the end */
/* after each remote procedure call.                            */
void __RPC_USER DATA_HANDLE_TYPE_unbind(DATA_HANDLE_TYPE dh1, 
                                      RPC_BINDING_HANDLE h1)
{
    RPC_STATUS status;
    status = RpcBindingFree(&h1); 
    ...
}