ITypeLib:GetLibAttr和ReleaseTLibAttr

时间:2015-12-23 19:43:13

标签: c++ com win32com typelib

问题:ITypeLib::GetLibAttr()方法分配了一个新的TLIBATTR结构,要求我调用ITypeLib::ReleaseTLibAttr()?这使得代码对我来说过于冗长,如果被忽视,它有可能导致内存泄漏。

如果我缓存结果,然后调用ReleaseTLibAttr(),使用缓存值时是否有任何副作用或潜在的陷阱?

TLIBATTR结构只是一组简单的值:

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

没有自己动态分配的成员。也许这可能会发生变化?

我写了一个简单的帮助方法,以防止需要调用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();
    }
}

在1到10的范围内,未来证据如何MyGetLibAttr()(错误处理除外)?使用缓存结果有任何副作用吗?

我意识到性能损失很小(额外调用memcpy()),但我们更关心的是代码维护和内存泄漏。

2 个答案:

答案 0 :(得分:4)

接口方法在1996年就是这样设计的,因为他们不想失去向结构中添加成员的机会。实际上并没有发生这种情况,TLIBATTR已经稳定了19年。并且永远不会再改变,微软已经放弃了.tlb格式,现在正在使用.winmd格式。

如果它让您感觉更好,那么.NET Framework also copies the structure

答案 1 :(得分:1)

您的代码没有任何问题 您可以在https://github.com/alexhenrie/wine/blob/master/dlls/oleaut32/typelib.c检查GetLibAttr的源代码 - ITypeLib2_fnGetLibAttr。
由于你已经加载了TypeLib,然后是guid,lcid,syskind,wMajorVerNum,wMinorVerNum,wLibFlags在下次加载TLB文件之前无法更改,并且只有在该文件被更改的情况下才会被更改。