The [context_handle] attribute identifies a binding handle that maintains context, or state information, on the server between remote procedure calls.
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); ]
Specifies one or more attributes that apply to the type.
Specifies a pointer type or a type identifier. An optional storage specification can precede type-specifier.
declarator and declarator-list
Specifies standard C declarators, such as identifiers, pointer declarators, and array declarators. The declarator for a context handle must include at least one pointer declarator. For more information, see Array and Sized-Pointer Attributes, arrays, and Arrays and Pointers. The declarator-list consists of one or more declarators, separated by commas. The parameter-name identifier in the function declarator is optional.
Specifies zero or more attributes that apply to the function. Valid function attributes are [callback], [local]; the pointer attribute [ref], [unique], or [ptr]; and the usage attributes [string], [ignore], and [context_handle].
Specifies zero or more pointer declarators. A pointer declarator is the same as the pointer declarator used in C; it is constructed from the * designator, modifiers such as far, and the qualifier const.
Specifies the name of the remote procedure.
Specifies zero or more directional attributes, field attributes, usage attributes, and pointer attributes appropriate for the specified parameter type. Separate multiple attributes with commas.
Specifies the identifier that specifies the context handle type as defined in a typedef declaration that takes the [context_handle] attribute. The rundown routine is optional.
Windows ServerÂ 2003 and WindowsÂ XP: A single interface can accommodate both serialized and nonserialized context handles, enabling one method on an interface to access a context handle exclusively (serialized), while other methods access that context handle in shared mode (nonserialized). These access capabilities are comparable to read/write locking mechanisms; methods using a serialized context handle are exclusive users (writers), whereas methods using a nonserialized context handle are shared users (readers). Methods that destroy or modify the state of a context handle must be serialized. Methods that do not modify the state of a context handle, such as those methods that simply read from a context handle, can be nonserialized. Note that creation methods are implicitly serialized.
The [context_handle] 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 Run-down 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:
- Context handles cannot be array elements, structure members, or union members. They can only be parameters.
- Context handles cannot have the [transmit_as] or [represent_as] attribute.
- Parameters that are pointers to [out] context handles must be [ref] pointers.
- An [in] context handle can be used as the binding handle and cannot be NULL.
- An [in, out context handle can be NULL on input, but only if the procedure has another explicit handle parameter. If there are no other explicit non-NULL context handle parameters, the [in, out] context handle cannot be NULL.
- A context handle cannot be used with callbacks.
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);