Search code examples
c++comwin32comtypelib

ITypeLib: GetLibAttr and ReleaseTLibAttr


Problem: The ITypeLib::GetLibAttr() method allocates a new TLIBATTR struct, requiring me to call ITypeLib::ReleaseTLibAttr()? This makes the code too verbose for my taste, and it has the potential for memory leaks if overlooked.

If I cache the result, then call ReleaseTLibAttr(), are there any side effects or potential pitfalls when using the cached value?


The TLIBATTR struct is just a set of simple values:

typedef struct tagTLIBATTR
{
    GUID guid;
    LCID lcid;
    SYSKIND syskind;
    WORD wMajorVerNum;
    WORD wMinorVerNum;
    WORD wLibFlags;
} TLIBATTR;

There are no members which are themselves dynamically allocated. Perhaps that is subject to change?


I wrote a simple helper method to prevent the need to call ReleaseTLibAttr().

HRESULT MyGetLibAttr(ITypeLib* pTypeLib, TLIBATTR *pTLibAttr)
{
    TLIBATTR *pTLibAttrTemp;
    HRESULT hr = pTypeLib->GetLibAttr( &pTLibAttrTemp );
    if ( SUCCEEDED(hr) )
    {
        memcpy( pTLibAttr, pTLibAttrTemp, sizeof(TLIBATTR) );
        pTypeLib->ReleaseTLibAttr( pTLibAttrTemp );
    }
    return hr;
}

void main()
{
    ITypeLib *pTypeLib;
    HRESULT hr = LoadTypeLibEx( ... , &pTypeLib);
    if ( SUCCEEDED(hr) )
    {
        TLIBATTR libAttr;
        hr = MyGetLibAttr( pTypeLib, &libAttr );
        if ( SUCCEEDED(hr) )
        {
            // Now we have a TLIBATTR object that we don't have to free.
        }
        pTypeLib->Release();
    }
}

On a scale of 1 to 10, how future proof is MyGetLibAttr() (error handling aside)? Are there any side effects to using the cached result?

I realize there is a small performance hit (the extra call to memcpy()), but the bigger concern for us is code maintenance and memory leaks.


Solution

  • The interface method was designed like this back in 1996 because they did not want to lose the opportunity to add members to the structure. That did not in fact happen, TLIBATTR has been stable for 19 years. And will never change again, Microsoft has moved away from the .tlb format and is now using the .winmd format.

    If it makes you feel any better, the .NET Framework also copies the structure.