ITypeLib:GetLibAttr 和 ReleaseTLibAttr

ITypeLib: GetLibAttr and ReleaseTLibAttr

问题: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() 的额外调用),但我们更关心的是代码维护和内存泄漏。

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

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

你的代码没有问题。
您可以在 https://github.com/alexhenrie/wine/blob/master/dlls/oleaut32/typelib.c - ITypeLib2_fnGetLibAttr.
查看 GetLibAttr 的源代码 由于您已经加载了 TypeLib,因此 guid、lcid、syskind、wMajorVerNum、wMinorVerNum、wLibFlags 不能更改,直到下一次加载 TLB 文件并且仅在该文件被更改的情况下。