typedef [context_handle [ , type-attribute-list ] ] type-specifier declarator-list;
[context_handle [, function-attr-list ] ] type-specifier [ptr-decl] function-name(
[ [parameter-attribute-list] ] type-specifier [declarator]
, ...
);
[ [ function-attr-list ] ] type-specifier [ ptr-decl ] function-name(
[context_handle [ , parameter-attribute-list ] ] type-specifier [declarator]
, ...
);
[ void __RPC_USER context-handle-type_rundown (context-handle-type); ]
typedef [context_handle] void * PCONTEXT_HANDLE_TYPE;
short RemoteFunc1([out] PCONTEXT_HANDLE_TYPE * pCxHandle);
short RemoteFunc2([in, out] PCONTEXT_HANDLE_TYPE * pCxHandle);
void __RPC_USER PCONTEXT_HANDLE_TYPE_rundown (PCONTEXT_HANDLE_TYPE);
The context_handle attribute identifies a binding handle that maintains context, or state information, on the server between remote procedure calls. The attribute can appear as an IDL typedef type attribute, as a function return type attribute, or as a parameter attribute.
When you apply the context_handle attribute to a type definition, you must also provide a context rundown routine. See Server Context Rundown Routine for details.
When you use the MIDL compiler in default (/ms_ext) mode, a context handle can be any pointer type selected by the user, as long as it complies with the requirements for context handles described here. The data associated with such a context handle type is not transmitted on the network and should only be manipulated by the server application. DCE IDL compilers restrict context handles to pointers of type void *. Therefore this feature is not available when you use the MIDL compiler /osf switch.
As with other handle types, the context handle is opaque to the client application and any data associated with it is not transmitted. On the server, the context handle serves as a handle on active context and all data associated with the context handle type is accessible.
To create a context handle, the client passes to the server an out, ref pointer to a context handle. (The context handle itself can have a null or non-null value, as long as its value is consistent with its pointer attributes. For example, when the context handle type has the ref attribute applied to it, it cannot have a null value.) Another binding handle must be supplied to accomplish the binding until the context handle is created. When no explicit handle is specified, implicit binding is used. When no implicit_handle attribute is present, an auto handle is used.
The remote procedure on the server creates an active context handle. The client must use that context handle as an in or in, out parameter in subsequent calls. An in-only context handle can be used as a binding handle, so it must have a non-null value. An in-only context handle does not reflect state changes on the server.
On the server, the called procedure can interpret the context handle as needed. For example, the called procedure can allocate heap storage and use the context handle as a pointer to this storage.
To close a context handle, the client passes the context handle as an in, out argument. The server must return a null context handle when it is no longer maintaining context on behalf of the caller. For example, if the context handle represents an open file and the call closes the file, the server must set the context handle to NULL and return it to the client. A null value is invalid as a binding handle on subsequent calls.
A context handle is only valid for one server. When a function has two handle parameters and the context handle is not null, the binding handles must refer to the same address space.
When a function has an in or an in, out context handle, its context handle can be used as the binding handle. In this case, implicit binding is not used and the implicit_handle or auto_handle attribute is ignored.
The following restrictions apply to context handles:
auto_handle, handle, handles, Context Handles, Server Context Rundown Routine, Multi-threaded Clients and Context Handles, Client Context Reset, RpcSsDestroyClientContext