COM:我可以在不调用Release的情况下调用CoUninitialize吗?

时间:2009-09-16 06:21:34

标签: com memory-leaks resource-leak

我怀疑。我初始化COM,做CoCreateInstance并使用一些接口。我可以在不调用Release的情况下调用CoUninitialize吗?它会导致任何内存/资源泄漏吗?

先谢谢, -Mani。

4 个答案:

答案 0 :(得分:3)

来自MSDN:

http://msdn.microsoft.com/en-us/library/ms688715%28VS.85%29.aspx

  

应该调用CoUninitialize   应用程序关闭,作为最后一次调用   之后发给COM库   应用程序隐藏其主窗口和   通过其主要的消息循环。   如果有开放式对话   剩下的,CoUninitialize开始了   模态消息循环并调度任何   来自容器的待处理消息   或此COM应用程序的服务器。通过   发送消息,   CoUninitialize确保了   应用程序之前没有退出   接收所有待处理的消息。   非COM消息将被丢弃。

你应该只在关机时调用CoUninitialize,到那时,如果你有内存泄漏并不重要。

答案 1 :(得分:2)

无论您是否取消初始化COM,省略对Release的调用都会导致对象在服务器端保持活动状态,从而可能无缘无故地保持整个服务器(如果不是作为服务运行)。换句话说,您将在服务器端出现内存泄漏,只能通过重新启动COM服务器来消除。

我记得第一次使用COM时问过类似的问题。我正在研究的客户端使用了很多线程,我试图为每个线程完成的不同任务重用接口。这使得管理接口缓存非常困难。最终,没有捷径。除非您使用MTA,GIT或接口封送,否则创建接口的线程也必须释放它。

为了方便您使用,请尝试使用CComPtr来管理您创建的界面。与常规指针一样,使用智能指针有时可以让您的生活更轻松。

答案 2 :(得分:1)

你不应该使用CoUninitialize()而不是为你的对象调用IUnknown::Release() - 这些是不同的功能。

IUnknown::Release()只会减少对象的引用计数,并可能导致其被破坏。如果没有使用编组,则通过vtable直接完成此调用(控件直接传递到COM服务器代码中),COM子系统甚至不为此做任何事情。

CoUninitialize()将为调用线程释放与COM相关的资源,我猜这是与编组相关的对象。如果没有使用编组,则对象将保持未发布状态,因为只有您的代码才知道它们。

这就是为什么你不应该使用一个而不是另一个。

答案 3 :(得分:0)

AFAIK,CoUninitialize“假定”释放当前线程上正在使用的所有COM资源。我不会依赖它。在调用uninitialise之前,我宁愿确保释放所有内容。