我有个疑问。我初始化 COM,做 CoCreateInstance 并使用一些接口。我可以在不调用 Release 的情况下调用 CoUninitialize 吗?它会导致任何内存/资源泄漏吗?
提前致谢,-Mani。
我有个疑问。我初始化 COM,做 CoCreateInstance 并使用一些接口。我可以在不调用 Release 的情况下调用 CoUninitialize 吗?它会导致任何内存/资源泄漏吗?
提前致谢,-Mani。
来自 MSDN:
http://msdn.microsoft.com/en-us/library/ms688715%28VS.85%29.aspx
CoUninitialize 应该在应用程序关闭时调用,因为在应用程序隐藏其主窗口并进入其主消息循环之后对 COM 库进行的最后一次调用。如果还有未完成的对话,CoUninitialize 会启动一个模式消息循环,并从容器或服务器为该 COM 应用程序分派任何待处理的消息。通过调度消息,CoUninitialize 确保应用程序在收到所有未决消息之前不会退出。非 COM 消息将被丢弃。
你应该只在关机时调用 CoUninitialize,到那时你是否有内存泄漏都没有关系。
无论您是否取消初始化 COM,省略对 Release 的调用都会导致对象在服务器端保持活动状态,可能会无缘无故地保持整个服务器正常运行(如果不作为服务运行)。换句话说,您将在服务器端出现内存泄漏,这只能通过重新启动 COM 服务器来消除。
我记得当我第一次开始使用 COM 时问过类似的问题。我正在处理的客户端使用了许多线程,我试图为每个线程完成的不同任务重用接口。这使得管理接口缓存变得非常困难。最终,没有捷径可走。除非您使用 MTA、GIT 或接口编组,否则创建接口的线程也必须释放它。
为了让您更轻松,请尝试使用CComPtr来管理您创建的接口。与常规指针一样,使用智能指针有时可以让您的生活更轻松。
您不应该使用 CoUninitialize()而不是调用IUnknown::Release()
您的对象 - 这些是完全不同的功能。
IUnknown::Release()
只会减少对象的引用计数并可能导致其破坏。如果不使用编组,则此调用直接通过 vtable 完成(控制直接传递到 COM 服务器代码),COM 子系统甚至不为此做任何事情。
CoUninitialize() 将为调用线程释放与 COM 相关的资源,我猜这些资源是与编组相关的对象。如果不使用编组,对象将保持未释放,因为只有您的代码知道它们。
这就是为什么你不应该用一个来代替另一个。
AFAIK,CoUninitialize “应该”释放当前线程上正在使用的所有 COM 资源。不过我不会依赖它。我宁愿确保在调用 uninitialise 之前释放所有内容。