在Visual Studio 2015 Windows窗体应用程序中的afxwin.h问题 [英] afxwin.h issues in Visual Studio 2015 Windows Form App

查看:2787
本文介绍了在Visual Studio 2015 Windows窗体应用程序中的afxwin.h问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前一段时间我写了一个C + + CLI窗体应用程序,它在Visual Studio 2013中编译得很好。现在我想在Visual Studio 2015 Update 1中重新编译,但我面临一个问题,经过几个小时的测试,我想原因是 afxwin.h






TL; DR - 是否有任何方式可以使用 stdafx.h (因此 afxwin.h








由于Windows Form在VS2015中不再作为项目模板使用,我创建了一个 CLR空项目调用测试



Ctrl-Shift-A添加 UI > MyForm



MyForm.cpp中添加了

  #includeMyForm.h

使用命名空间System;
using namespace System :: Windows :: Forms;

[STAThread]
int main(cli :: array< System :: String ^> ^ args)
{
Application :: EnableVisualStyles
Application :: SetCompatibleTextRenderingDefault(false);
Test :: MyForm form;
应用程序:: Run(%form);
}

配置属性 / em>> > Configuration Properties > >



COMPILE(DEBUG CONFIGURATION):编译时没有错误/警告



MyForm.cpp 运行

现在,尝试添加 afxwin.h / em>:

  #include< afxwin.h> 

配置属性> 使用MFC 在共享DLL中使用MFC



COMPILE(DEBUG CONFIGURATION) strong>无错误/警告的编译



运行:应用程序甚至不会启动,只是显示调试失败>表达式中的错误 _CrtIsValidHeapPointer(block)






现在要解决这个错误,我发现有必要删除入口点,所以:



配置属性> 链接器> 没有错误/警告



运行:该应用程序再也无法启动,它不再显示调试失败,但未知模块中的System.AccessViolationException 和尝试读取或写入受保护的内存。这通常表示其他内存已损坏。






< img src =http://i.stack.imgur.com/qvr7Z.pngalt =enter image description here>
这些是我在我的应用程序中得到的错误, m不知道如何简单地包括 afxwin.h 在VS2015中提供所有这些问题,而它在VS2013中不。



<

解决方案

C运行时库被James McNellis重写为VS2015。他是一个大的C ++粉丝,他写的新代码受到慢性SIOF问题的困扰,这在C ++程序中是如此常见。静态初始化命令Fiasco肯定存在于你的VS2013项目中,但发生不是字节,原来的CRT代码暴露在SIOF多年,可能表现得更好。



在这种情况下过于难以调试,失败的代码来自CRT源代码文件,不包括在名为thread_safe_statics.cpp的安装中。不是100%肯定它的作用,因为没有源代码看,但文件名称几乎没有想象力。



MFC有静态,需要在可用之前被初始化。特别地,程序必须具有在恰当的时间初始化的静态CWinApp变量。这需要入口点是WinMain(),在MFC中实现,以及在源代码中显式声明CWinApp实例。像这样:

  [STAThread] 
int main(cli :: array< System :: String ^> ^ args)
{
Application :: EnableVisualStyles();
Application :: SetCompatibleTextRenderingDefault(false);
Application :: Run(gcnew Test :: MyForm);
}

class MyMfcApp:public CWinApp {
public:
virtual int Run()override {
return main(__ nullptr);
}
} MyApp;

将链接器的EntryPoint设置重置为其默认值(空白),以便首先初始化CRT,然后MFC的WinMain函数运行。并且要小心我采取了一个捷径,你不会得到 args 。我修复了一个在main()函数中的错误,它使用了错误的堆栈语义。



这个破解让你的程序再次运行。是否实际上是正确的是相当可疑的。这受到与大框架相关的Who is the Boss综合征的困扰。不要依赖任何MFC窗口正常工作,因为它是分发消息的Winforms。但你应该在VS2013有这个问题。 不要这样做是唯一可靠的建议。


A while ago i wrote a C++ CLI Windows Form app, which compiled fine in Visual Studio 2013. Now i wanted to recompile it in Visual Studio 2015 Update 1 but i'm facing a problem, and after hours of tests i figured out the culprit is afxwin.h.


TL;DR - Is there any way i can use stdafx.h (so afxwin.h and all other imports coming with it) in a Windows Form app compiled with Visual Studio 2015 without having the app crash upon start?


Here's how to reproduce the same issues i'm facing in my app.

Since Windows Form is no longer available as project template in VS2015, i created a CLR Empty Project called Test

Ctrl-Shift-A to add a UI > Windows Form called MyForm

In MyForm.cpp i added this:

#include "MyForm.h"

using namespace System;
using namespace System::Windows::Forms;

[STAThread]
int main(cli::array<System::String^>^ args)
{
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Test::MyForm form;
    Application::Run(%form);
}

Under Configuration Properties > Linker > Advanced i set Entry Point to main

Under Configuration Properties > Linker > System i set SubSystem to Windows (/SUBSYSTEM/WINDOWS)

COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings

RUN: runs without any problem.

Now lets try adding afxwin.h to MyForm.cpp:

#include <afxwin.h>

Under Configuration Properties > General i set Use of MFC to Use MFC in a shared DLL

COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings

RUN: the app wont even start, it just shows Debug Assertion Failed error in expression _CrtIsValidHeapPointer(block)

Now to fix this error i found that it's necessary to remove the Entry Point, so:

Under Configuration Properties > Linker > Advanced i removed Entry Point value (which i previously set to main)

COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings

RUN: the app again wont even start, it no longer shows Debug Assertion Failed but System.AccessViolationException in an unknown module and "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

These are the errors i get in my app, and i'm wondering how is it possible that simply including afxwin.h gives all these problems in VS2015 while it didnt in VS2013.

Is there anything i can do to fix it, without going back to VS2013?

解决方案

The C runtime library was significantly rewritten for VS2015 by James McNellis. He's a big C++ fan, the new code he's written suffers from the chronic SIOF problem that's so common in a C++ program. The Static Initialization Order Fiasco was surely present in your VS2013 project as well but happened not to byte, the original CRT code was exposed to SIOF for many years so likely to behave better.

Excessively hard to debug in this case, the code that fails comes from a CRT source code file that is not included in the install named thread_safe_statics.cpp. Not 100% sure what it does given that there's no source code to look at but the name of the file leaves little to the imagination.

MFC has static state that needs to be initialized before it is usable. In particular, the program must have a static CWinApp variable that is initialized at Just the Right Time. That requires the entrypoint to be WinMain(), implemented in MFC, and an explicit declaration of a CWinApp instance in your source code. Like this:

[STAThread]
int main(cli::array<System::String^>^ args)
{
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Application::Run(gcnew Test::MyForm);
}

class MyMfcApp : public CWinApp {
public:
    virtual int Run() override {
        return main(__nullptr);
    }
} MyApp;

Reset the linker's EntryPoint setting back to its default (blank) so the CRT is initialized first and MFC's WinMain function runs next. And beware I took a shortcut, you get no args. And I fixed a bug in your main() function, it used stack semantics incorrectly.

This hack gets your program running again. Whether it is actually correct is rather doubtful. This suffers from the "Who is the Boss" syndrome that's associated with big frameworks. Don't depend on any MFC window to work correctly since it is Winforms that is dispatching messages. But you should have had that problem in VS2013 as well. "Don't do it" is the only solid advice.

这篇关于在Visual Studio 2015 Windows窗体应用程序中的afxwin.h问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆