一个很诡异的异常,AfxOleGetMessageFilter()->Register()断言失败

wolfmvp 2015-11-26 03:31:39
最近在调试ModbusServer程序,原文链接:这里,Debug模式下碰到一个断言失败,调试了许久,没找到问题的原因所在,看看这里有没大神可以助我一臂之力。异常函数如下:

BOOL AFXAPI AfxOleInit2()
{
_AFX_THREAD_STATE* pState = AfxGetThreadState();
ASSERT(!pState->m_bNeedTerm); // calling it twice?

// Special case DLL context to assume that the calling app initializes OLE.
// For DLLs where this is not the case, those DLLs will need to initialize
// OLE for themselves via OleInitialize. This is done since MFC cannot provide
// automatic uninitialize for DLLs because it is not valid to shutdown OLE
// during a DLL_PROCESS_DETACH.
if (afxContextIsDLL)
{
pState->m_bNeedTerm = -1; // -1 is a special flag
return TRUE;
}

// first, initialize OLE
//SCODE sc = ::OleInitialize(NULL);
SCODE sc = ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
//SCODE sc = ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);

if (FAILED(sc))
{
// warn about non-NULL success codes
TRACE1("Warning: OleInitialize returned scode = %s.\n",
AfxGetFullScodeString(sc));
goto InitFailed;
}
// termination required when OleInitialize does not fail
pState->m_bNeedTerm = TRUE;

// hook idle time and exit time for required OLE cleanup
CWinThread* pThread; pThread = AfxGetThread();
pThread->m_lpfnOleTermOrFreeLib = AfxOleTermOrFreeLib;

// allocate and initialize default message filter
if (pThread->m_pMessageFilter == NULL)
{
pThread->m_pMessageFilter = new COleMessageFilter;
ASSERT(AfxOleGetMessageFilter() != NULL);
AfxOleGetMessageFilter()->Register();
}

#ifdef _MAC
CWinApp* pApp; pApp = AfxGetApp();
#ifndef _WINDLL
// Mac MFC uses a static version of ole2ui which must be initialized
if (pState->m_bNeedTerm && !::OleUIInitialize(pApp->m_hInstance,
pApp->m_hPrevInstance, SZCLASSICONBOX, SZCLASSRESULTIMAGE))
goto InitFailed;
#endif

_afxPfnOleAuto = NewAEEventHandlerProc(_AfxOleAutoHandler);
if (_afxPfnOleAuto != NULL)
{
AEInstallEventHandler('OLE2', 'AUTO', _afxPfnOleAuto, (long) pApp, false);
}
#endif

return TRUE;

InitFailed:
AfxOleTerm();
return FALSE;
}
...全文
506 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2015-11-27
  • 打赏
  • 举报
回复
ASSERT(pFactory == NULL || AfxIsValidAddress(pFactory, sizeof(COleObjectFactory))); 到底是 哪个?
wolfmvp 2015-11-27
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
注意
delete pThread->m_pMessageFilter;
试过,Debug模式依旧报断言错误。
schlafenhamster 2015-11-27
  • 打赏
  • 举报
回复
“无法在线Debug” 是 debug 的 new 问题 ?,试试 静态 分配
wolfmvp 2015-11-27
  • 打赏
  • 举报
回复
引用 7 楼 schlafenhamster 的回复:
AfxIsValidAddress
BOOL AfxIsValidAddress( const void* lp, UINT nBytes, BOOL bReadWrite = TRUE );

Return Value

Nonzero if the specified memory block is contained entirely within the program’s memory space; otherwise 0.

Parameters

lp

Points to the memory address to be tested.

nBytes

Contains the number of bytes of memory to be tested.

bReadWrite

Specifies whether the memory is both for reading and writing (TRUE) or just reading (FALSE).

Remarks

Tests any memory address to ensure that it is contained entirely within the program’s memory space. The address is not restricted to blocks allocated by new.


改变 size 和 bReadWrite 试试, 如
AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));
这个函数位于安装目录下的OLELINK.CPP文件中(“C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\OLELINK.CPP”),并不属于应用层函数。目前该工程最大的遗憾就是无法在线Debug,Release模式下可以实现所需要的功能。
schlafenhamster 2015-11-27
  • 打赏
  • 举报
回复
AfxIsValidAddress BOOL AfxIsValidAddress( const void* lp, UINT nBytes, BOOL bReadWrite = TRUE ); Return Value Nonzero if the specified memory block is contained entirely within the program’s memory space; otherwise 0. Parameters lp Points to the memory address to be tested. nBytes Contains the number of bytes of memory to be tested. bReadWrite Specifies whether the memory is both for reading and writing (TRUE) or just reading (FALSE). Remarks Tests any memory address to ensure that it is contained entirely within the program’s memory space. The address is not restricted to blocks allocated by new. 改变 size 和 bReadWrite 试试, 如 AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));
wolfmvp 2015-11-27
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
ASSERT(pFactory == NULL ||
AfxIsValidAddress(pFactory, sizeof(COleObjectFactory)));
到底是 哪个?
这个“AfxIsValidAddress(pFactory, sizeof(COleObjectFactory))”
schlafenhamster 2015-11-26
  • 打赏
  • 举报
回复
注意 delete pThread->m_pMessageFilter;
wolfmvp 2015-11-26
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
Then, in the InitInstance() of the CWinApp derived class, unregister the IMessageFilter MFC registers for you when calling AfxOleInit(). Add this code after the call to AfxOleInit(). Then instantiate a class of type CMyMessageFilter and register it: BOOL CmyApp::InitInstance() { // Initialize OLE libraries and registers default message filter. if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } CWinThread* pThread = AfxGetThread(); if (pThread != NULL) { // Destroy message filter, thereby unregistering it. delete pThread->m_pMessageFilter; pThread->m_pMessageFilter = NULL; // Create the new message filter object. pThread->m_pMessageFilter = new CMyMessageFilter; ASSERT(AfxOleGetMessageFilter() != NULL); // Register the new message filter object. AfxOleGetMessageFilter()->Register(); } ... ... }
我贴的源码中,这个地方的处理也没啥不妥。
    // allocate and initialize default message filter
    if (pThread->m_pMessageFilter == NULL)
    {
        pThread->m_pMessageFilter = new COleMessageFilter;
        ASSERT(AfxOleGetMessageFilter() != NULL);
                AfxOleGetMessageFilter()->Register();
    }
跟你贴的源码区别不大,我Debug的时候,单步到这里跳出那个断言失败窗口。
BOOL COleLinkingDoc::Register(COleObjectFactory* pFactory, LPCTSTR lpszPathName)
{
	USES_CONVERSION;

	ASSERT_VALID(this);
    // 程序在这里跳出断言失败窗口
	ASSERT(pFactory == NULL ||
		AfxIsValidAddress(pFactory, sizeof(COleObjectFactory))); 
	ASSERT(lpszPathName == NULL || AfxIsValidString(lpszPathName));
	ASSERT(m_dwRegister == 0);

	// attach the document to the server
	ASSERT(m_pFactory == NULL || m_pFactory == pFactory);
	m_pFactory = pFactory;

	BOOL bResult = TRUE;

	// create file moniker based on path name
	RELEASE(m_lpMonikerROT);
	m_strMoniker.Empty();
	if (lpszPathName != NULL)
	{
		if (CreateFileMoniker(T2COLE(lpszPathName), &m_lpMonikerROT) != S_OK)
			bResult = FALSE;
	}

	// register file moniker as running
	if (m_lpMonikerROT != NULL)
	{
		// see if the object is already running in the ROT
		LPRUNNINGOBJECTTABLE lpROT = NULL;
		VERIFY(GetRunningObjectTable(0, &lpROT) == S_OK);
		ASSERT(lpROT != NULL);
		LPUNKNOWN lpUnk;
		if (lpROT->GetObject(m_lpMonikerROT, &lpUnk) == S_OK)
		{
			// fatal error -- can't register same moniker twice!
			lpUnk->Release();
			RELEASE(m_lpMonikerROT);
			return FALSE;
		}
		// not already running -- so ok to attempt registration
		SCODE sc = lpROT->Register(NULL, (LPUNKNOWN)
			GetInterface(&IID_IUnknown), m_lpMonikerROT, &m_dwRegister);
		lpROT->Release();
		m_strMoniker = lpszPathName;
		if (sc != S_OK)
			bResult = FALSE;
	}

	// update all objects with new moniker
	POSITION pos = GetStartPosition();
	COleClientItem* pItem;
	while ((pItem = GetNextClientItem(pos)) != NULL)
	{
		if (pItem->m_bMoniker)
		{
			ASSERT(pItem->m_lpObject != NULL);
			pItem->m_lpObject->SetMoniker(OLEWHICHMK_CONTAINER,
				m_lpMonikerROT);
		}
	}

	return bResult;
}
schlafenhamster 2015-11-26
  • 打赏
  • 举报
回复
Then, in the InitInstance() of the CWinApp derived class, unregister the IMessageFilter MFC registers for you when calling AfxOleInit(). Add this code after the call to AfxOleInit(). Then instantiate a class of type CMyMessageFilter and register it: BOOL CmyApp::InitInstance() { // Initialize OLE libraries and registers default message filter. if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } CWinThread* pThread = AfxGetThread(); if (pThread != NULL) { // Destroy message filter, thereby unregistering it. delete pThread->m_pMessageFilter; pThread->m_pMessageFilter = NULL; // Create the new message filter object. pThread->m_pMessageFilter = new CMyMessageFilter; ASSERT(AfxOleGetMessageFilter() != NULL); // Register the new message filter object. AfxOleGetMessageFilter()->Register(); } ... ... }

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧