1

我使用“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 编译应用程序时,它表现得很好。

这可能是什么原因?

4

4 回答 4

3

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

于 2008-10-15T16:38:30.040 回答
3

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

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

_ATL_DEBUG_INTERFACES

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

于 2008-10-15T17:25:12.677 回答
1

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

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

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

于 2008-10-15T18:37:35.230 回答
1

以下为我解决了它:在包含控件的窗口中,添加一个 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();
}
于 2009-04-24T10:22:59.923 回答