2011-09-28 15 views
3

这可能会更好地指向Microsoft的支持,但想知道是否有人对此有何看法。为什么我的DLL在使用MFC作为Visual Studio 2010中的DLL时在MFC SDI程序中使用时泄漏?

我创建了一个简单的C++ DLL类似如下:

//simpledll.h 
class simpledll { 
    public: 
    __declspec(dllexport) simpledll(); 
    __declspec(dllexport) ~simpledll(); 
} 

//someheader.h 
#include <string> 
const std::string SomeString(L"I'm Leaking"); 

//simpledll.cpp 
#include "simpledll.h" 
#include "someheader.h" 
//some code to generate memory leak debug messages 
simpledll::simpledll(){ /*code to register for memory leak debug messages*/} 
simpledll::~simpledll(){} 

接下来,我使用VS 2010的默认设置在为MainFrm.h我#包括使一个通用的MFC SDI(单文档界面)的应用程序“simpledll.h”并创建一个成员变量:simpledll mSimpleDLL;

这里是它变得有趣的地方。如果我编译DLL和适用于v100的MFC应用程序(都使用/ MDd开关),只需启动然后关闭应用程序就会产生内存泄漏。如果我在MFC应用程序中将“使用MFC”设置更改为在静态库中使用MFC,则泄漏消失。然后,如果我重新编译针对v90的DLL并使用MFC的DLL版本重新编译MFC应用程序,则不会发生内存泄漏。切换DLL以使用v100和MFC应用程序使用v90并且无内存泄漏。实际上,似乎产生内存泄漏的唯一组合是当DLL和MFC应用程序目标v100和MFC应用程序使用MFC作为共享DLL时。我甚至在VS11开发人员的预览版中尝试过这一点,并且在针对v110时,一切正常。

有没有人遇到过这个问题?它仅限于VS2010中的SDI MFC应用程序吗?什么可能导致这些泄漏?我假设它在调用SomeString常量的析构函数之前终止了DLL,但为什么要将MFC用作DLL?

+0

Google“静态初始化命令失败”。 –

+0

谢谢。我注意到,在我发布这个消息之前,将所有wstrings改为wchar_t []解决了这个问题,但是不知道为什么。它似乎与MFC静态/ DLL绑定的事实仍然让我感到奇怪。 – bsruth

回答

0

我相信这只是SomeString初始化与调用AfxEnableMemoryTracking()(如果我没记错的话)的问题。实际上,内存泄漏可能发生在其他版本中,但SomeString可能在内存泄漏跟踪被激活之前被分配,或者在检查发生之前被释放(不太可能,样本中没有任何清除)。

您可以尝试通过为SomeString分配新值来显示泄漏,并使用longuer字符串来确保完成新的内存分配。从simpledll的构造函数中完成。但首先,你必须在simpledll.cpp文件中移动字符串声明,否则你会在每个包含someHeader.h的.cpp文件中得到一个新的实例。

编辑:它不是特定于MFC,会发生在任何DLL上,但是当MFC自动启用内存泄漏检测时,它在MFC应用程序中变得更加明显。

0

两个和一个年半后...

我转换是没有用MFC到旨在通过MFC程序加载的非MFC DLL一个不平凡的独立的应用程序。一切正常,但VS 2010调试器报告无尽的内存泄漏。

线索是这些内存泄漏报告退出之前的DLL清理函数被调用。

有这里采用的是一个同样详细和复杂的解决方案的详细讨论:

http://www.vis-sim.com/3dsceneBB/viewtopic.php?t=1027

是涉及指定MFC库的依赖。然而,有一个更简单的解决方案:

  1. 在属性页面 - >连接器 - >输入,将您的DLL文件名添加到“延迟加载的DLL”。
  2. 在相同的对话框选项卡中,将“delayimp.lib”添加到“其他依赖项”。

甲方案替代(具有延迟加载DLL的优点和缺点的讨论一起)可以在这里找到:

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

这里的优点是,延迟加载DLL之前卸载MFC DLL被卸载,所以MFC不再报告错误的内存泄漏。

请注意,这仅需要为了抑制假内存泄漏消息的调试版本做了你的DLL。该DLL仍然可以在RELEASE版本中静态链接,从而避免延迟链接DLL的缺点。

相关问题