一个很诡异的异常,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;
}
...全文
425 9 打赏 收藏 转发到动态 举报
写回复
用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(); } ... ... }
第一章 基础篇1. 第1节 - Mid journey register Discord和Midjourney 并将Midjourney BOT添加至自己的服务器 Midjourney入门到精通2. 第2节 - Midjourney教程 用Mid journey画一条狗 知识点:Midjourney基本用法、U和V是什么、查询账号信息和Midjourney付费套餐说明3. 第3节 - Midjourney 教程 Mid journey imagine指令详解 知识点:Midjourney prompt结构、AR指令4. 第4节 - Midjourney教学 Mid journey imagine指令详解 知识点:用Midjourney V4和Niji模型 画出卡通风格的绘图5. 第5节 - Midjourney教程 CHAOS参数详解 知识点:用Chaos指令激发Mid journey的创造力 第二章 进阶篇6. 第6节 - Midjourney 教学 Seed参数 以图作图 知识点:用Seed指令在Mid journey中进行连续创作7. 第7节 - Midjourney进阶教程 光和权重 知识点:如何通过在midjourney中打光提高图片质感 双冒号权重的实战用法8. 第8节 - Midjourney 角色设计 知识点:在midjourney中进行卡通角色概念设计 通过修改种子角色达到对角色的控制9. 第9节 - Midjourney LOGO设计教学 知识点:--no参数 | remix mode | ChatGPT + Midjourney结合使用10. 第10节 - Midjourney + DALL·E 2 角色设计以图作图 知识点:用DALL·E 2将Midjourney的图片进行拓图和改图 实现角色的连续创作11. 第11节 - Midjourney VS DALL·E 2 AI绘图网站哪家强?用Midjourney和DALL·E 2风别进行人物⧸动物⧸风景⧸风格化⧸设计创作 最全测评12. 第12节 - Midjourney + DALL·E 2 手部修复 知识点:用DALL·E 2修复Mid journey图片的一些问题 通过渐进式修复实现对AI的控制13. 第13节 - Midjourney生成风格化图片 知识点:提交Midjourney一张照片 通过Midjourney进行照片的风格化创作14. 第14节 - Midjourney生成风格化图片 知识点:用过渡图的方式,在Midjourney中进行照片的风格化创作15. 第15节 - Midjourney生成风格化照片 知识点:用过渡图的方式在Midjourney中进行照片的风格化的一点补充说明16. 第16节 - ⧸describe 是啥?Midjourney最新命令⧸describe魔鬼测试 知识点:describe命令用法 | describe风格测试17. 第17节 - ⧸describe 是啥?Midjourney最新命令⧸describe魔鬼测试 知识点:用describe命令识别logo 第三章 常见问题18. 第18节 - Midjourney常见问题解答 知识点:seed获取 | 如何写prompt | 试用和付费 | 描述报错等问题19. 第19节 - Midjourney V5来了!全网最全V5模型测试视频 包括手部⧸面部修复、图片分辨率提升、--iw参数在以图作图中的应用

3,245

社区成员

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

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