ActiveX 插件导致 ASSERT 在 VS2008 中的应用程序退出时失败

Posted

技术标签:

【中文标题】ActiveX 插件导致 ASSERT 在 VS2008 中的应用程序退出时失败【英文标题】:ActiveX plugin causes ASSERT to fail on application exit in VS2008 【发布时间】:2008-10-15 15:52:57 【问题描述】:

我使用“ESRI MapObjects LT2”ActiveX 插件的 MFC 应用程序在关闭它时向我抛出了一个 ASSERT。 错误发生在cmdtarg.cpp

CCmdTarget::~CCmdTarget()

#ifndef _AFX_NO_OLE_SUPPORT
    if (m_xDispatch.m_vtbl != 0)
        ((COleDispatchImpl*)&m_xDispatch)->Disconnect();
    ASSERT(m_dwRef <= 1); //<--- Fails because m_dwRef is 3
#endif
    m_pModuleState = NULL;

我使用 VC9 构建了(本机 C++)应用程序。 当我使用 VC6 编译应用程序时,它的表现很好。

这可能是什么原因?

【问题讨论】:

【参考方案1】:

这看起来像一个引用计数。这个“目标”是否可以被其他东西引用,而不是释放它?

【讨论】:

天啊!我刚刚注意到问题上的“引用计数器”标签。对不起。 :-( 没问题.. 我尽量让所有相关信息都易于发现;不过在这里没用,我猜...【参考方案2】:

您可以跟踪定义 _ATL_DEBUG_INTERFACES 的 Addref 和 Release 调用

来自http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx

_ATL_DEBUG_INTERFACES

在包含任何 ATL 头文件之前定义此宏,以将组件接口上的所有 AddRef 和 Release 调用跟踪到输出窗口。

【讨论】:

【参考方案3】:

使用_ATL_DEBUG_INTERFACES 没有产生任何额外的输出... 我在stdafx.h 的第一行定义了它,直接在#pragma once 之后,所以我想这已经足够早了。

也许原因是我使用 ActiveX 控件的方式: 我不会自己打电话给AddRef()Release()。 MapObjects 安装程序附带了包含大量包装类的示例代码,这些类必须由 VC6 或更早版本生成。 我尝试使用 VC9 自己生成包装类,但出现了我无法修复的错误。 我通过让我的一个窗口有一个类型为CMap1(派生自CWnd)的成员来使用控件,这是生成的包装类之一。在CMyWnd::OnCreate() 中,我也调用CMap1::Create(),就这样,我完成了:我可以添加一个图层,控件会显示世界地图。 我几乎不知道引用计数的内容是什么,因为我没有添加或发布任何引用。至少不是故意的……

该控件相当陈旧:.OCX 文件的版本信息中包含 2000 年。 它也不再被官方支持,但我没有任何替代品。

【讨论】:

【参考方案4】:

以下为我解决了这个问题: 在包含控件的窗口中,添加一个 OnDestroy() 处理程序:

void CMyWnd::OnDestroy()

    // Apparently we have to disconnect the (ActiveX) Map control manually
    // with this undocumented method.
    COleControlSite* pSite = GetOleControlSite(MY_DIALOG_CONTROL_ID);
    if(NULL != pSite)
    
        pSite->ExternalDisconnect();
    

    CWnd::OnDestroy();

【讨论】:

以上是关于ActiveX 插件导致 ASSERT 在 VS2008 中的应用程序退出时失败的主要内容,如果未能解决你的问题,请参考以下文章

在 Microsoft Access 中安装 VLC ActiveX 插件的问题

基于MFC的ActiveX控件开发教程------------浏览器插件之ActiveX开发

中国银行 密码不能填

ActiveX网页截图插件

ActiveX提示信息插件

谷歌 不支持 activeX插件