问题: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()
),但我们更关心的是代码维护和内存泄漏。
答案 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文件之前无法更改,并且只有在该文件被更改的情况下才会被更改。