背景:我有一个带有MFC UI的大型遗留C ++应用程序。我正在尝试重构项目并将其迁移到新的.Net用户界面。现在作为第一步,我试图将Visual Studio 2015中的MFC exe项目重构为一个常规的MFC dll,我可以从exe项目中调用它。 (见下文)我们计划逐步将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
当我断开构造函数
时,这是我的callstackMfcDll.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 ++。
答案 0 :(得分:1)
事实证明遗留代码已经在本地覆盖了:: operator new(),并且它正在做一些复杂的事情,现在已经破坏了。这特别令人困惑,因为我在线上有一个断点 char * mem = new char [10];
和F11没有进入new的本地实现,直到我在new()函数中实际设置了一个断点。
所以基本上是家用脚枪...... 叹。谢谢您的帮助。
答案 1 :(得分:0)
在dll的加载时间内调用构造函数。也许到那时候堆还没有为dll初始化。
初始化代码的正确位置是InitInstance和ExitInstance或DllMain,您也可以在其中进行清理。将构造函数和析构函数代码移到那里。