TypeLib containment refcounting

Kelly Leahy kellyleahy at swbell.net
Mon Jun 16 15:53:19 CDT 2003


----- Original Message ----- 
From: "Mike Hearn" <mike at theoretic.com>
To: <wine-devel at winehq.com>
Sent: Monday, June 16, 2003 3:16 PM
Subject: Re: TypeLib containment refcounting


> On Mon, 16 Jun 2003 14:43:25 -0500, Sir Kelly Leahy scribed thus:
> > I would expect you to addref the typelib when the ITypeInfo pointer is
> > created, and then when it is destroyed to release it.
>
> I believe that's what I'm doing. Maybe not.
>
> I think what is actually going on, is that this method returns a pointer
> to an internal interface that's always present. There is no construction
> as such. From MSDN:
>
> HRESULT GetTypeInfoOfGuid(
>   REFGUID  guid,
>   ITypeInfo FAR* FAR*  ppTinfo
> );
> Retrieves the type description that corresponds to the specified GUID.
>
>
> This confuses me. Does the caller need to release the interface? The page
> doesn't mention refcounting at all.
>
> "Retrieves" is somewhat fuzzy. The fact that it's a pointer to a pointer
> suggests that maybe you get a pointer to an internal interface and you
> shouldn't do any refcounting on it.
>

The caller should release the object when they're done with it.  I guess
what I was saying is that there's a few ways this can be done.

One way is for ITypeInfo_AddRef() to addref the type library object that
contains it (i.e. add one to the refcount on the ITypeLib struct in C
terms).  It can either do this every time (in which case,
ITypeInfo_Release() should release the type library object each time) or it
can do it only when the refcount is zero on entry to ITypeInfo_AddRef() (in
which case ITypeInfo_Release() should only Release() the type library object
when the result of decrementing the refcount is zero in
ITypeInfo_Release()).

Another way is the addref the type library when the ITypeInfo wherever a
ITypeInfo interface is initially created (like in GetTypeInfoOfGuid) but I
think this is more dangerous, since then you have to have some way for this
refcount to go away, and ITypeInfo_Release() doesn't know who created it,
just that it was created.  If you are careful enough to always put an addref
on the library when you create a new ITypeInfo pointer (GetTypeInfoOfGuid,
GetTypeInfo, IDispatch::GetTypeInfo, etc.) but this seems like a unwieldy
task to guarantee that the code is right in all of these places.  It's much
easier to make the ITypeInfo_AddRef() and ITypeInfo_Release() call
ITypeLib_AddRef() and ITypeLib_Release() on the containing ITypeLib
implementation when appropriate.

> > In the object that implements the ITypeInfo reference, you should have a
> > pTypeLib->Release() in the destructor and a pTypeLib->AddRef() somewhere
in
> > the code that creates the ITypeInfo implementing object.
>
> Well that's C++ stuff. Remember that all this is implemented in pure C.
> The relevant code searches a linked list for a ITypeInfoImpl struct, which
> stores all the data and the COM Vtable. It then casts it to an ITypeInfo
> and incs the refcount:
>
>     *ppTInfo = (ITypeInfo*)pTypeInfo;
>     ITypeInfo_AddRef(*ppTInfo);
>
> So, what you actually get out of this method is a pointer to an internal
> data structure rather than a constructed object....
>


Sorry...  I didn't have the source handy to look at (RMAing my linux box HDD
right now!)

As far as C++ stuff vs. C stuff, in essence the pointer to the data
structure (including the VMT) is simply a C++ style class without the C++,
and with some special requirements...  You can just replace my p->method()
with OBJECT_method(p) if you like to make it look like what I've seen from
wine.  I'm still pretty new to the wine source, so it may not be like this
everywhere, I just don't have the time to look.

Kelly




More information about the wine-devel mailing list