The
Ubiquitous IUnknown interface
Gopalan Suresh Raj
Food for Thought... |
|
|
All COM+ interfaces derive from IUnknown. Every COM+ component exposes at least the IUnknown interface. There is no default implementation of IUnknown as it is an abstract base class. The only reason
that there is a class definition of IUnknown is to provide a
signature for invoking its methods as they are implemented by a
concrete class. The actual definition of IUnknown
from the system header files also includes a declaration
specification to ensure that the stack frame will be consistently
formed by all COM clients and component implementations.
The IUnknown interface is used to express the base
functionality of all COM+ objects which are:
1. Life Time Control of the COM+ object (a 'la Variable
Liveliness Notification) and
2. Type Coersion.
This IUnknown interface as defined in the unkwn.idl as follows:
|
Lifetime Control of the COM+
object
COM+ mandates client programs to manage the reference count of
each interface pointer that it uses. It is considered a very bad
programming style to simply allow process termination to clean up
any unreleased resources. Therefore, COM+ has very specific rules
that the client has to follow. The AddRef()/Release() implementation of the IUnknown
interface sometimes controls the lifetime of a COM+ object. Some
objects use a client-controlled reference count to control the
lifetime of an object. Other objects do not allow COM reference
counting to affect the lifetime of the object. However, for
uniformity, clients always call AddRef and
Release according to COM+'s reference counting
rules. All interface pointers must adhere to this rule. So the
client always follows the rules.
Rules for invoking AddRef/Release methods on COM+ objects
|
Look at the following client-side code fragment:
|
In the above code fragment note
that:
1. The method returns a COM+ Object pointer to the client through
the ppOuterObject parameter.
2. AddRef'ing of interface pointers happen as close to the
assignment as is possible.
The three most
important rules to Resource Management in COM+ are:
1. AddRef()must be called each time a non-null
interface pointer is copied from one location in memory to the
other.
2. Release()
must be called each time a non-null interface pointer is
overwritten or destroyed in memory.
3. Redundant AddRef()/Release()
operations can be eliminated
if we have special knowledge of the two memeory locations
involved.
Similarly,
Also Note the following:,
1. Calls to AddRef must be matched by an equal number of calls to
Release on the same pointer value. This is to ensure that objects
do per-instance reference counting properly. Interface pointers
are resources, just like memory and other operating system
primitives. Once a pointer has been AddRef'ed, you have to call
Release in all code paths including exceptions.
2. Once all AddRef's have been offset by Release calls, the
pointer value is considered invalid.
3. The ULONG results of AddRef and Release are not guaranteed to
be accurate.
4. Be careful with exceptions. All Interface pointers should be
set to zero after they have been released. This will ensure that
you do not accidentally access an object that has deleted itself.
Type Coersion and QueryInterface
|
QueryInterface is the typecast operator of COM+. It is used to access additional functionality of any COM+ object. In some ways, look at it as the logical equivalent of the dynamic_cast<> operator available in the C++ language or the type-casting functionality available in the Java language.
When you have an interface
pointer to an object and would like to access some other
interface of the same object, you would invoke QueryInterface
through the interface that you are holding on the object. If the
call to QueryInterface had succeeded and had returned an S_OK
result, the interface pointer returned as the second parameter
will contain a valid AddRef'ed COM+ object that corresponds to
the requested interface. When you are finished using the
component, it is your responsibility to call Release through the
new interface pointer.
However, if the call to QueryInterface fails, it means that the
object does not support the requested interface, the function
will return E_NOINTERFACE and the second parameter will not have a
valid object. If the QueryInterface call fails, you need not call
Release on the object.
Take a look at the following IDL:
|
The following examples illustrate
the use of QueryInterface to traverse the type heirarchy of an
object using Visual C++, Visual Basic and Visual J++.
Shown below is the Visual C++ code-snippet of a COM client trying
to use QueryInterface:
|
Shown below is the Visual Basic code-snippet of a COM client trying to use QueryInterface:
|
Shown below is the Visual J++ code-snippet of a COM client trying to use QueryInterface:
|
Note that in all the above code-snippets,
Release is called only when a new pointer is successfully
returned by Query interface.
![]() |
click here to go
to My Basic COM+ Tutorial... |
click here to go
to My Advanced COM+/DNA Tutorial HomePage... |
About the Author... |
Gopalan Suresh Raj is a Software Architect, Developer and an active Author. He is contributing author to a couple of books "Enterprise Java Computing-Applications and Architecture" and "The Awesome Power of JavaBeans". His expertise spans enterprise component architectures and distributed object computing. Visit him at his Web Cornucopia© site (http://www.execpc.com/~gopalan) or mail him at gopalan@execpc.com. |
This site was developed and is maintained by Gopalan Suresh Raj This page has been visited |
Last Updated : Mar 14,'99 |
Copyright (c) 1997-2000, Gopalan Suresh Raj - All rights reserved. Terms of use. |
All products and companies mentioned at this site are trademarks of their respective owners. |