Мое приложение MFC, использующее плагин ActiveX «ESRI MapObjects LT2», выдает мне АССЕРТ при закрытии.
Ошибка возникает в 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;
}
Я создал (родное C++) приложение с VC9. Когда я компилирую приложение с помощью VC6, оно ведет себя нормально.
Что могло быть причиной этого?





Это похоже на счетчик ссылок. Может ли на эту «цель» ссылаться что-то еще, что-то, что ее не выпускает?
Нет проблем .. Я стараюсь, чтобы всю необходимую информацию было легко найти; я думаю, здесь не сработало ...
Вы можете отслеживать вызовы Addref и Release, определяющие _ATL_DEBUG_INTERFACES.
от http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx
_ATL_DEBUG_INTERFACES
Определите этот макрос перед включением любых файлов заголовков ATL для отслеживания всех вызовов AddRef и Release на интерфейсах ваших компонентов в окне вывода.
Использование _ATL_DEBUG_INTERFACES не дало никаких дополнительных результатов ...
Я определил его в первой строке stdafx.h, сразу после #pragma once, так что я думаю, что это достаточно рано.
Возможно, причина в том, как я использую элемент управления ActiveX:
Я не звоню на AddRef() или Release() в одиночку.
Установщик MapObjects поставляется с образцом кода с множеством классов-оболочек, которые, должно быть, были сгенерированы VC6 или чем-то более ранним.
Я сам пытался сгенерировать классы-оболочки с помощью VC9, но возникли ошибки, которые я не смог исправить.
Я использую этот элемент управления, позволяя одному из моих окон иметь член типа CMap1 (производный от CWnd), который является одним из этих сгенерированных классов-оболочек. В CMyWnd::OnCreate() я также вызываю CMap1::Create(), и все, готово: я могу добавить слой, и элемент управления отображает карту мира.
Я почти не знаю, что такое подсчет ссылок, поскольку я не добавлял и не выпускал никаких ссылок. По крайней мере, не зря ...
Элемент управления довольно старый: в информации о версии файла .OCX указан 2000 год. Он также официально больше не поддерживается, но у меня нет замены.
Для меня это решило следующее: В окне, содержащем элемент управления, добавьте обработчик 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();
}
Ооо! Я только что заметил метку "счетчик ссылок" в вопросе. Извиняюсь. :-(