代码之家  ›  专栏  ›  技术社区  ›  foraidt

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

  •  1
  • foraidt  · 技术社区  · 16 年前

    我的MFC应用程序使用“esri mapobjects lt2”ActiveX插件在关闭它时向我抛出断言。 错误发生在 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编译应用程序时,它表现得很好。

    为什么会这样?

    4 回复  |  直到 15 年前
        1
  •  3
  •   Head Geek    16 年前

    这看起来像一个参考计数。这个“目标”能被其他东西引用吗,一些不释放它的东西?

        2
  •  3
  •   Alessandro Jacopson    16 年前

    您可以跟踪addref和release调用定义 _ATL_DEBUG_INTERFACES

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

    _ATL_DEBUG_INTERFACES
    

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

        3
  •  1
  •   foraidt    16 年前

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

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

    控件已经很旧了,.ocx文件的版本信息中包含2000年。
    它也不再得到官方的支持,但我没有任何替代品。

        4
  •  1
  •   foraidt    15 年前

    下面为我解决了这个问题: 在包含控件的窗口中,添加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();
    }
    
    推荐文章