【发布时间】:2017-05-25 16:48:26
【问题描述】:
背景:我有一个带有 MFC UI 的大型遗留 C++ 应用程序。我正在尝试重构项目并将其迁移到新的 .Net UI。现在,作为第一步,我正在尝试将 Visual Studio 2015 中的 MFC exe 项目重构为可以从 exe 项目中调用的常规 MFC dll。 (见下文)我们计划逐渐将 UI 从 MFC 迁移到 .Net。我们正在尝试在飞机在空中时更换引擎...
无论如何,我在使用旧版 C++ 应用程序中的各种静态和全局变量时遇到了麻烦。当我将新的 dll 加载到 exe 中时,我得到一个访问冲突的异常。结果发现堆没有在 dll 中正确创建,我不明白为什么....
我将问题缩小到一个带有文件级静态变量的非常简单的结构。该变量在正常应用程序逻辑之前调用库加载时的构造函数。
在 MfcDll 项目的 SomeData.cpp 中
struct SomeData {
SomeData()
{
::OutputDebugString("construct data\n");
char* mem = new char[10]; // nope
if (mem)
{
::OutputDebugString("got mem\n");
}
else
{
::OutputDebugString("no heap\n");
}
}
};
SomeData fileLevelStatic;
输出是:
construct data
no heap
这是我在构造函数断点时的调用堆栈
MfcDll.dll!SomeData::SomeData() Line 57 C++
MfcDll.dll!`dynamic initializer for 'fileLevelStatic''() Line 63 C++
ucrtbased.dll!00007ffdc88f947d() Unknown
MfcDll.dll!dllmain_crt_process_attach(HINSTANCE__ * const instance, void * const reserved) Line 67 C++
MfcDll.dll!dllmain_crt_dispatch(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 133 C++
MfcDll.dll!dllmain_dispatch(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 190 C++
MfcDll.dll!_DllMainCRTStartup(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 249 C++
ntdll.dll!00007ffe005da35f() Unknown
那么我在这里做错了什么?我需要做什么以确保我有一个可用于静态对象的堆。旧版应用程序广泛使用静态和全局变量。是的,我们想重构这些,但这是一项艰巨的任务,所以我们需要在我们这样做的同时保持它的工作......
另外,为了验证它不是 .Net 与 MFC 的关系,我正在仅使用 C++ 的解决方案中进行此特定测试。我有 MFCDll、传统的静态链接 C++ 库和一个 C++ 中的股票窗口应用程序项目,它引用了 MFCDll。所以 .Net 目前甚至不在代码中……它都是带有 MFC 和 Windows 的 C++。
【问题讨论】:
-
您的整个项目是否使用相同的运行时支持版本和内存模型?
-
什么是静态构造函数?
-
在解决方案项目属性中,所有项目(静态库、dll和exe项目)都使用“多线程调试DLL(/MDd)” dll设置为“在a中使用MFC共享 DLL"
-
“静态构造函数”也许我说错了。静态对象的构造函数,在某些情况下需要做复杂的事情并访问堆,就是问题所在。所以 SomeData fileLevelStatic;在应用程序代码之前调用构造函数 SomeData::SomeData()
标签: c++ visual-c++ dll mfc