【问题标题】:exception during destruction of CComPtr销毁 CComPtr 期间的异常
【发布时间】:2011-03-18 07:49:14
【问题描述】:

我有一个成员变量声明为

CComPtr<IXMLDOMDocument2> m_spXMLDoc;

XML 文档是这样创建的

CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument2, (void**)&m_spXMLDoc));

现在,当应用程序退出时,会引发异常。调用栈指向p-&gt;Release()

~CComPtrBase() throw()
{
   if (p)
      p->Release();
}

当我在 VS 调试器中将鼠标悬停在 p 上时,它指向了一些有效内存。

最后一个调用栈指向msxm6中的异常

msxml6.dll!3d6cXX03() 

任何建议,可能是什么原因?我认为这不是CComPtr 问题。

【问题讨论】:

  • 手动发布()或滥用其他 CComPtrs(例如通过Attach())可能是一个原因。如果其他一切看起来都很好,那么也可能是其他问题导致内存损坏。
  • 对象的生命周期是多少?什么时候调用析构函数?
  • 你找到原因了吗?我刚刚遇到了类似的问题(除了我使用的是调试接口访问 SDK COM 类,但可能不关心使用的确切 com 类)。我怀疑这与 CComPtr 实现错误或其他有关。

标签: exception visual-c++ com atl smart-pointers


【解决方案1】:

我遇到了类似的问题,最终我发现这只是一个错误。我必须确保在CComPtr 被破坏之后调用CoUninitialize()。否则会出现异常。

int _tmain(int argc, _TCHAR* argv[]) {
  CoInitialize(NULL);
  mymain(); 
  //put all logic in a separate function so that CComPtr
  //is destructed before CoUninitialize()
  CoUninitialize();
  return 0;
}

在与CoUninitialize() 调用相同的函数中声明CComPtr 将导致异常,因为在函数终止后发生销毁。

【讨论】:

  • 另一种方法是将使用CComPtr 声明的代码放入嵌套块中。另一种选择是手动调用CComPtr::Release()。两者都将解决完全相同的问题,只是略有不同。
【解决方案2】:

在程序退出之前执行此操作:

if( m_spXMLDoc.p )
    m_spXMLDoc.Release();

我亲眼目睹了这一点。这个问题与引用计数有关(显然),但我从不关心寻找原因。希望这会有所帮助!

【讨论】:

    【解决方案3】:

    您应该使用 CComPtr 的成员函数创建实例:

    m_spXMLDoc.CoCreateInstance(...)
    

    【讨论】:

      【解决方案4】:

      我正在研究一个类似的问题,即 IExplorer 从客户端下抓取当前网页的 com 服务器。
      结果似乎无法执行释放,而是出现 com 错误,例如服务器已断开客户端。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-17
        • 2015-10-28
        • 1970-01-01
        相关资源
        最近更新 更多