zoukankan      html  css  js  c++  java
  • 收到 wincore.cpp 中一个 " ASSERT " BUG: 当 MFC 应用程序 Visual C++ 中 MFC 规则 DLL 中调用函数声明

    今日将VC2005写的DLL的源码转到VC6时,弹出对话框时,报告:

    ---------------------------
    Microsoft Visual C++ Debug Library
    ---------------------------
    Debug Assertion Failed!

    Program: D:\工作目录\Topology VC6.0\Bin\Test_Topology.exe
    File: wincore.cpp
    Line: 884

    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation on asserts.

    (Press Retry to debug the application)
    ---------------------------
    终止(A)   重试(R)   忽略(I)  
    ---------------------------

    image

    经查,好像是VC6的Bug。

    http://support.microsoft.com/kb/194300/zh-cn

    收到 wincore.cpp 中一个 " ASSERT " BUG: 当 MFC 应用程序 Visual C++ 中 MFC 规则 DLL 中调用函数声明

    我的总结:在调用Dll中资源时尽量用下边的语句代替AFX_MANAGE_STATE(AfxGetStaticModuleState());可以绕过这个错误。

        //AFX_MANAGE_STATE(AfxGetStaticModuleState());
        HMODULE hDLL=GetModuleHandle("SpatialReference.dll");
        HINSTANCE hEXE=AfxGetResourceHandle();
        AfxSetResourceHandle((HINSTANCE)hDLL);
        //函数返回之前:
        // AfxSetResourceHandle(hEXE);

    微软网站的解决办法是:

    症状

    当 MFC EXE SDI / MDI 应用程序上下文中的命令处理程序调用 MFC 规则 DLL, 创建模式对话框, MFC 中导出函数以下断言可能触发:

    ASSERT wincore.cpp 行 884 中
    ASSERT wincore.cpp 行 883 中

    如果忽略, 应用程序行为通常断言。 EXE 和规则 DLL 必须动态链接到 MFC。

    回到顶端

    原因

    当父未显式指定模式对话框, MFC PreModal() 调用中确定与调用到 CWnd::GetSafeOwner_() 父。该调用返回路由框架 (AfxGetThreadState() "-> m_pRoutingFrame)。 m_pRoutingFrame 分配命令处理程序中。 [ 请参阅 CFrameWnd::OnCmdMsg() 中 CPushRoutingFrame ]
    EXE, 到框架窗口是 EXE 中命令处理程序中设置路由框架。 因为线程状态是 EXE 和 DLL, 中相同 AfxGetThreadState() "-> m_pRoutingFrame 返回 EXE 框架窗口。 临时柄映射是 DLL, 为 CDialog::PreModal() 调用当调用 CWnd::FromHandle(::GetActiveWindow()) 中路由框架中创建临时 CWnd。 此断言, CWnd::AssertValid(), 中由事实路由框架临时 CWnd 的规则 DLL 临时柄映射中存在不匹配。
    此问题影响的规则 DLL, 其中 CWnd::GetSafeOwner_() 称为上下文中命令处理程序中创建的所有模式窗口。 CWnd::GetSafeOwner_() 称为模式窗口的创建过程。 这包括 MFC 消息框、 OLE 属性页、 CDatabase::Connect、 对话框、 属性页和 OLE 忙对话框中。 请注意因为 CWnd::GetSafeOwner_() 是不调用在此上下文中, 此问题不影响无模式窗口不。

    回到顶端

    解决方案

    一个解决办法是: 暂时在是 DoModal() 调用期间设置 AfxGetThreadState() "-> m_pRoutingFrame 到 NULL。 可以使用以下代码:

    class tempRoutingFrame {
    
       CFrameWnd* m_pFrame ;
    
    public:
    
       tempRoutingFrame(CFrameWnd * pWnd= NULL)
       {
          // Save current value
          m_pFrame = AfxGetThreadState()->m_pRoutingFrame;
          // Set to value passed in. NULL by default.
          AfxGetThreadState()->m_pRoutingFrame = pWnd;
       }
       ~tempRoutingFrame()
       {
          // Restore m_pRoutingFrame to original value.
          AfxGetThreadState()->m_pRoutingFrame = m_pFrame;
       }
    
    };
    
    extern "C" void __declspec(dllexport) TestFunction();
    
    void TestFunction()
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState())
       #ifdef _DEBUG
       // Workaround for ASSERT in WINCORE.CPP 884 (CWnd::AssertValid)
       tempRoutingFrame rframe;
       #endif
       CMyDialog dlg;
       dlg.DoModal();
    }
    				
    其他解决办法, 对对话框和属性表, 而言是要明确设置对话框中的父级如下:
    void TestFunction()
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState())
       CMyDialog dlg(AfxGetMainWnd());
       dlg.DoModal();
    }
    				

    回到顶端

    状态

    Microsoft 已确认这是了本文开头列出 Microsoft 产品中存在错误。
    早在 Visual Studio 6.0 Service Pack 3 中得到解决此错误。 有关 VisualStudio, ServicePack 详细信息请单击下列文章编号, 查看 Microsoft 知识库文章中文章:

    194022 (http://support.microsoft.com/kb/194022/) Visual Studio 6.0 服务包, 什么, 其中, 为什么

    194295 (http://support.microsoft.com/kb/194295/) 如何判断安装 VisualStudio 服务包

    回到顶端

    更多信息

    复现行为的步骤

    1.使用应用程序向导创建常规 MFCDLL 项目。

    2.确定和取消按钮和一个编辑控件, 创建新的对话框框资源。

    3.创建对于从 CDialog 派生对话框类。 命名该类 CMyDialog。

    4.mydialog.cpp 中添加下列函数:

    extern "C" void __declspec(dllexport) TestFunction();
    
    void TestFunction()
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       CMyDialog dlg;
       dlg.DoModal();
    }
    					

    5.生成 DLL。

    6.创建默认应用程序向导应用 EXE 项目。

    7.使用以下替换 OnAppAbout 函数:

    extern "C" void __declspec(dllimport) TestFunction();
    
    void CMyTestApp::OnAppAbout()
    {
       TestFunction();
    }
    					

    8.添加导出库向第 6 步中创建项目第 5 步中创建。

    9.将步骤 5 到 Debug 文件夹为第 6 步中生成应用程序中生成 DLL。

    10.生成并运行。

    11.在 帮助 菜单上, 单击 关于 。

    结果 : ASSERTS wincore.cpp, 中 883 和 884 行被触发。

    回到顶端

    参考

    MFC 模块状态实现 TN058:

  • 相关阅读:
    MATLAB中mexFunction函数的接口规范
    opencv 人脸识别 (一)训练样本的处理
    VS 编程常见错误及解决方法
    在用VC编译下debug和release的什么区别
    OpenCV中Mat的详解
    主成份分析PCA
    人脸识别必读的N篇文章
    opencv有关错误及解决办法
    解决办法:CMake编译时出现“error in configuration process project files may be invalid”
    mybatis 学习笔记(二):mybatis SQL注入问题
  • 原文地址:https://www.cnblogs.com/flyingfish/p/803170.html
Copyright © 2011-2022 走看看