这两天在设计一个项目,独立了几个DLL模块。昨天勉强把前段工作做完了,需要的DLL也都挂进了EXE文件之中,暗自高兴了一把。不过晚上在看的时候,发现VS2005输出窗口提示有内存泄露:
a CDynLinkLibrary object at...
心里总觉得不爽 L
今天去Google搜索了一下,第一篇是:当您使用多个MFCDLL 报告内存泄漏
http://support.microsoft.com/kb/167929/zh-cn
由于是“注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。”所以没有怎么仔细看。
后来通过注释代码发现,原因可能是因为一个DLL内部使用另一个DLL中的导出类造成的。于是将这两个DLL合并到一个DLL中,再链接到EXE中测试,果然没了J
但是我又不想将这两个DLL合并到一起,因为另一个DLL是“通用”的。我在想,这倒底是什么原因呢?一生气,算了,直接搞个Win32 DLL,也不使用什么MFC DLL。
建立好Win32 DLL之后,拷贝以前DLL中的类到项目,加进去编译。编译器却提示说:什么MFC工程需要MFC DLL支持。再一想,原来是因为以前的MFC DLL向导会默认包含stdafx.h。纯Win32 DLL不需要这个。突然之间,又想到了一个问题:那篇自动翻译的提到了什么UNICODE与ANSI。
原文如下:
与 ANSI (MFC40d.DLL) 的 MFC 版本生成 MFC 应用程序调用 MFC USRDLL, 它与 UNICODE (MFC40Ud.DLL) 的 MFC 版本生成。 MFC 版本使用相同 C 运行时库 (CRT) DLL, MSVCR40d.DLL。 由于 MFC USRDLLs 是框 " 黑色 - ", 应从 ANSI MFC 应用程序调用 UNICODE MFC USRDLL 没有问题。
但是, 以来 (MFC40ud.DLL) UNICODE 和 ANSI (MFC40d.DLL) MFC DLL 都使用同一 CRTDLL, MFC USRDLL 中分配所有对象上报告假内存泄漏。 这是因为 MFC 依靠 CRTDLL 来分配和跟踪所有内存。 它并不分开来自不同版本的 MFC 内存分配。 当 MFC DLL 之一卸载, 它调用 CRT 进行内存转储, 假定所有处于堆是内存泄漏。 但是, 此假定是错误因为有两多份 MFC 内存中。
这有问题么?立马打开所有的DLL项目,
看到突显的这块了么,我的项目中有的DLL使用的是Unicode字符集,有的使用的是多字节字符集。然后将所有的DLL使用多字节字符集进行编译,生成EXE。一看,没了。看来,项目中使用的DLL字符集要保持一致,怪不得有些库会编译出好多版本来,然后在它的包含文件,根据预处理的定义加载“正确”的DLL。