----- Original Message ----- From: "Mike Hearn" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> 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