C ++调用COM DLL中的函数可能发生内存泄漏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++调用COM DLL中的函数可能发生内存泄漏相关的知识,希望对你有一定的参考价值。
我使用VC ++ 2017创建了一个C ++控制台应用程序。随着时间的推移,它会从第三方COM DLL中检索数据。我使用像CComSafeArray和CComVariant这样的COM类来管理自己的释放。
随着时间的推移,我发现在每次COM调用后,我的应用程序的内存在任务管理器中稳定增加。
我已经使用CRT库(https://docs.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019)来尝试检测内存泄漏,但它表明我没有。
我的问题是:
- COM一般是否有自己的内存管理,CRT库无法检测到但与我的进程有关?
- 如果是#1,是否有可用于检测COM内存泄漏的工具?
- 如果#1是这种情况,有没有办法垃圾收集COM内存?
谢谢你的考虑。
编辑4-19-2019我发现COM Dll返回VARIANT和BSTR的函数调用结果。我将它们分别分配给_variant_t和_bstr_t,以便提供自动清理(理论上)。例如。
_variant_t v = GetSomeVariant();
_bstr_t b = GetSomeString();
DLL不使用CoTaskMemAlloc,但它确实使用SysAllocString来生成BSTR。
_bstr_t b = GetSomeString();
据推测,那就是BSTR GetSomeString();
。哪个编译器意味着wchar_t* GetSomeString
; BSTR
告诉你它使用COM语义,但编译器不知道。那些语义是你称之为SysFreeString
。
_bstr_t::_bstr_t( wchar_t* str )
复制str
。是的,_bstr_t::~_bstr_t
然后将调用SysFreeString
,但它在副本上这样做。你需要在SysFreeString
上打电话给BSTR GetSomeString();
。
解决方案是_bstr_t::_bstr_t( BSTR bstr , bool fCopy )
与fCopy=false
。每个MSDN:
此构造函数由类型库头中的包装函数使用,以封装并获取由接口方法返回的BSTR的所有权。
对于VARIANT
,请参阅_variant_t::_variant_t(VARIANT& varSrc, bool fCopy);
。同样的想法。
COM不使用任何自动垃圾收集;尽管有可用的辅助类来处理引用计数,但一切都必须考虑在内。
COM中的约定是,如果被调用的方法分配了一些内存,那么调用者必须使用CoTaskMemFree
释放它。您可能需要检查您调用的DLL方法的代码,如果它们返回DLL分配的缓冲区中的任何内容,则需要通过调用CoTaskMemFree
释放该缓冲区。
见https://docs.microsoft.com/en-us/windows/desktop/learnwin32/memory-allocation-in-com
更多细节在这里:https://docs.microsoft.com/en-us/windows/desktop/com/memory-management-rules
以上是关于C ++调用COM DLL中的函数可能发生内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章