如何初始化堆,以便静态构造函数可以在常规 MFC dll 中使用堆?

How to initialize the heap so it can be used by static constructors in a regular MFC dll?

本文关键字:dll MFC 常规 构造函数 初始化 静态      更新时间:2023-10-16

>背景:我有一个带有MFC UI的大型遗留C++应用程序。我正在尝试重构项目并将其迁移到新的 .Net UI。 现在,作为第一步,我正在尝试将Visual Studio 2015中的MFC exe项目重构为可以从exe项目中调用的常规MFC dll。 (见下文)我们计划逐步将 UI 从 MFC 移动到 .Net。 我们正试图在飞机在空中时更换发动机......

无论如何,我在旧版C++应用程序中的各种静态和全局变量方面遇到了问题。当我将新的 dll 加载到 exe 中时,我收到一个异常,其中包含访问冲突。事实证明,在 dll 中没有正确创建堆,我不明白为什么......

我将问题缩小到一个非常简单的结构,其中包含文件级静态变量。该变量在正常应用程序逻辑之前在库加载时调用构造函数。

在 SomeData 中.cpp在 MfcDll 项目中

struct SomeData {
SomeData()
{
::OutputDebugString("construct datan");
char* mem = new char[10]; // nope
if (mem)
{
::OutputDebugString("got memn");
}
else
{
::OutputDebugString("no heapn");
}
}
};
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++库和一个引用 MFCDll 的股票窗口应用程序项目C++。 所以 .Net 在这一点上甚至不在代码中......它与MFC和Windows C++。

事实证明,遗留代码已在本地覆盖了 ::operator new(),并且它正在做一些复杂的事情,现在已经损坏了。 这特别令人困惑,因为我在 char* mem = new char[10] 行
上有一个断点;

F11 直到我实际在 new() 函数中放置了一个断点,才进入 new 的本地实现。

所以基本上是自制的脚枪... 叹息。 感谢您的帮助。

构造函数在 dll 的加载期间调用。也许到那时堆甚至还没有为 dll 初始化。

初始化代码的正确位置是 InitInstance 和 ExitInstance 或 DllMain,您也可以在其中进行清理。将构造函数和析构函数代码移动到此处。