Cover | Table of Contents | Colophon
CoGetObjectContext(
)
(see Figure 2-5). All objects in the same context
get the same context object.
CoGetObjectContext( ) is defined as:
HRESULT CoGetObjectContext(REFIID riid, void** ppInterface);
CoGetObjectContext( ) is always an IID that
specifies which interface to retrieve. Two of the context
object's interfaces, IObjectContext and
IObjectContextActivity, are legacy interfaces from
MTS and are provided primarily for backward compatibility with MTS
components running under COM+. The other two interfaces,
IContextState
and
IObjectContextInfo
, are specific to COM+. Throughout
this book, all chapters use these two interfaces, rather than the
legacy MTS interfaces.
IContextState interface controls object
deactivation (discussed in Chapter 3) and
transaction voting (discussed in Chapter 4) by
manipulating state bits in the context object.
CoGetCallContext(
)
(see Figure 2-6). The CoGetCallContext(
) signature is defined as:
HRESULT CoGetCallContext(REFIID riid, void** ppInterface);
CoGetCallContext( ) will fail and
return the error code
RPC_E_CALL_COMPLETE
. You can, however, still access the
context object, which exists as long as the context exists, and whose
pointer can be cached by the objects associated with it.
ISecurityCallContext
and
IServerSecurity
.
CoMarshalInterface(
)
and CoUnmarshalInterface(
)
functions. When you need to manually marshal an interface pointer
from Context A to Context B, you would serialize the interface
pointer into a stream in Context A using CoMarshalInterface(
), and get it out of the stream using
CoUnmarshalInterface( ) in Context B. This
sequence would manually set up proxies in Context B for accessing the
object. You can also use the
CoCreate and Release calls from
the client. Implementing IObjectControl is
optional, but I strongly recommend it. As always, a call to
IObjectControl::Activate( ) marks entry to a
context, and a call to IObjectControl::Deactivate(
) marks an exit. COM+ calls
IObjectControl::CanBePooled( ) after every
Deactivate( ), letting the object decide whether
it wants to be recycled or destroyed. This life cycle is shown in
Figure 3-9. When you configure your component to
support both JITA and object pooling, COM+ deactivates the object
every time the done bit is set and returns it to the pool instead of
releasing it. New method calls are served by recycled objects from
the pool, not with new instances.
CoCreateInstance( ) or CreateObject(
) do not accept initialization parameters, you have to work
to gain access to the constructor string.
IObjectConstruct
, defined as:
interface IObjectConstruct : IUnknown
{
HRESULT Construct([in]IDispatch* pConstructionObj);
};
E_NOINTERFACE
. They will fail because COM+ will
refuse to hand over to the client an object that could not be
initialized properly. IObjectConstruct has only
one method, Construct(
)
,
which COM+ uses to pass in a pointer to another interface called
IObjectConstructString
, defined as:
interface IObjectConstructString : IDispatch
{
[id(1),propget] HRESULT ConstructString([out, retval] BSTR* pVal);
};
IObjectConstruct::Construct( ) to deliver the
string only once, immediately after calling the object constructor.
Note that COM+ passes the construction string to your object before
the call to IObjectControl::Activate( ), since the
initialization parameter should provide generic, rather than
context-specific, information.