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

发布于 2024-07-07 21:28:17 字数 470 浏览 14 评论 0 原文

我的 MFC 应用程序使用“ESRI MapObjects LT2”ActiveX 插件,在关闭它时向我抛出一个 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 编译该应用程序时,它表现良好。

这可能是什么原因?

My MFC application using the "ESRI MapObjects LT2" ActiveX plugin throws an ASSERT at me when closing it.
The error occurs in 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;
}

I built the (native C++) application with VC9.
When I compile the application with VC6, it behaves nicely.

What could be the reason for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

予囚 2024-07-14 21:28:17

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

That looks like a reference count. Could this "target" be referenced by something else, something that's not releasing it?

帝王念 2024-07-14 21:28:17

_ATL_DEBUG_INTERFACES 的 Addref 和 Release 调用

您可以从 "nofollow noreferrer">http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx

_ATL_DEBUG_INTERFACES

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

You can trace the Addref and Release calls defining _ATL_DEBUG_INTERFACES

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

_ATL_DEBUG_INTERFACES

Define this macro before including any ATL header files to trace all AddRef and Release calls on your components' interfaces to the output window.

芸娘子的小脾气 2024-07-14 21:28:17

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

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

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

Using _ATL_DEBUG_INTERFACES did not yield any additional output...
I defined it on the first line of stdafx.h, directly after #pragma once so I guess this is early enough.

Maybe the reason is how I am using the ActiveX control:
I'm not calling AddRef() or Release() by myself.
The MapObjects Installer comes with sample code with lots of wrapper classes which must have been generated by VC6 or something earlier.
I tried to generate wrapper classes myself with VC9 but there occured errors which I wasn't able to fix.
I use the control by letting one of my windows have a member of type CMap1 (derived from CWnd), which is one of those generated wrapper classes. In CMyWnd::OnCreate() I also call CMap1::Create() and that's it, I'm finished: I can add a layer and the control displays a world map.
I have pretty much no idea what the reference-count stuff is about as I have not added or released any references. At least not knowingly...

The control is pretty old: The .OCX file has the year 2000 in its version information.
It's also not officially supported anymore but I don't have any substitue.

叫嚣ゝ 2024-07-14 21:28:17

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

The following solved it for me:
In the window that contains the control, add an OnDestroy() handler:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文