为什么我的COM工厂在程序生命周期内从未发布过?

时间:2010-10-27 13:26:25

标签: windows visual-c++ com winapi ole

我有一个原生的C ++ ATL进程内COM服务器。一个单独的测试程序

  • 致电CoInitialize()
  • 调用CoCreateInstance(),然后调用
  • 在指针上调用Release()
  • 然后拨打CoUnitialize()并退出。

如果我在Visual C ++调试器下运行测试程序,则调试CRT会报告单个内存泄漏,并且每次分配编号都相同。

我使用an allocation hook并发现没有返回堆的对象是类工厂对象。

所以基本上会发生以下情况:

  • 程序调用{​​{1}}
  • COM内部调用CoCreateInstance()
  • ATL实例化工厂并将所有权传递给调用者(COM internals)

然后工厂永远不会被释放 - 我看不到对班级工厂DllGetClassObject()的足够电话。

发生了什么事?这是COM运行时中的缺陷吗?

1 个答案:

答案 0 :(得分:2)

原来这是ATL实施的问题。

服务器使用全局CComModule类实例。调用CComModule::DllClassObject()时,它会创建一个类工厂实例,并将其缓存在CComModule对象引用的映射中。所以实际上CComModule对象拥有类工厂。当CComModule析构函数运行时,它不会释放缓存的类工厂。

为了释放所有缓存的类工厂CComModule::Term(),应在卸载服务器之前调用方法。 IMO最简洁的方法是从CComModule派生并在派生类析构函数中调用CComModule::Term()