From
looking at the type library, you can see that
_Animal
is derived from another interface called
IDispatch
. What is not apparent is that
IDispatch
is derived from yet another interface
called IUnknown
. Actually, all interfaces are
ultimately derived from IUnknown
. This means that
all COM components share a dependable commonality.
The IUnknown
interface contains three methods:
QueryInterface
AddRef
Release
The purpose of
QueryInterface
is to allow clients to discover
whether a component supports a given interface. It is also used to
navigate between interfaces on a given component. Before returning
the requested interface (if it exists), AddRef
is
called to give the object a reference count.
AddRef
and Release
are
used for reference counting. All objects in memory have an associated
reference count. Every time an object is created or copied, this
count is incremented by one. Every time an object is released, the
reference count is decremented by one. When the reference count is
zero, the object can safely unload itself. As a VB programmer, you
have seen this entire process many times in code fragments like the
following, probably without ever realizing precisely what was
happening behind the scenes:
Dim Cow1 As Animal 'QueryInterface Animal for Cow interface and call AddRef. 'Cow1 now has a reference count of one. Set Cow1 = New Cow Dim Cow2 As Cow 'AddRef is called. Reference count is two. Set Cow2 = Cow1 'Release Cow1. Reference count is one Set Cow1 = Nothing 'Release Cow2. Reference count is 0 so component is unloaded. Set Cow2 = Nothing
The VB implementation of IUnknown
resides in
STDOLE2.TLB and looks like Example 2.5.
Example 2-5. IUnknown Interface Definition
[ odl, uuid(00000000-0000-0000-C000-000000000046), hidden ] interface IUnknown { [restricted] HRESULT _stdcall QueryInterface( [in] GUID* riid, [out] void** ppvObj); [restricted] unsigned long _stdcall AddRef( ); [restricted] unsigned long _stdcall Release( ); };
Every method of IUnknown
has the
[restricted]
attribute. This keeps you, the VB
programmer, from calling any of these methods directly. You can try,
though. Run the following code fragment:
Dim x As IUnknown x.AddRef
When you declare the IUnknown
variable, it will
not be displayed in the Auto Quick Info drop-down. This is because
the interface is marked with the [hidden]
attribute. If you enter all the code in lowercase, VB will adjust the
case for your entry. So we know that VB knows about this interface;
it’s just not talking. But you won’t be able to compile
this fragment, and if you try to run the code from the IDE, you will
get a nasty message like the one shown in Figure 2.5. Fortunately, we can work around this
limitation, but we’ll discuss that later.
Refer to Example 2.3 for a moment. Find the first line of IDL inside the library block that is not a comment. It looks like this:
importlib("STDOLE2.TLB");
This line of IDL causes the Animals type library to contain all of
the definitions found in stdole2.tlb.
Incidentally, stdole2.tlb
contains the
definition of IUnknown
(among other things) that
is used by VB. If you are interested, you can use OLE View to examine
this type library. The type library is called OLE Automation (Version
2.0).
18.188.229.246