绪论
当我开始使用VC++6.0进行GDI+和MFC编程后,我遇到了一些麻烦的问题:
- 不移除DEBUG_NEW 宏就不能编译有MFC的GDI代码
- 不少许修改代码就不能编译有STL的GDI+代码
- 不能探测到内存泄露
以下是解决方案
怎样使用
在stdafx.h文件中包含 GdiplusH.h
// GDI+ helper file
#include "GdiplusH.h"
特征
- 程序启动时候将初始化GDI+
- 你可以使用函数
_CrtXXX
来检查内存泄露,设置一个断点,保存并且比较内存状态,等等 - 内存泄露信息将在(VC)窗口输出
- 没有
DEBUG_NEW
方面的编译问题 - 没有STL方面的编译问题
内存泄露检查
GDI+使用GdipAlloc
和GdipFree
为GDI+对象分配内存。大概它们在gdiplus.dll有自己的内存分配表,但不幸的是,那没有输出API去得到内存泄露信息。GDI+对象能在栈上定位(例:在函数中创建一个局部变量),这些内存区域没有设置初始值,所以我们可以不使用GdipAlloc
或者GdipFree
函数。如果我们调用CRT调试内存分配和释放函数的版本代替GdipAlloc
/Free
,
我们使用有名的_CrtXXX
函数可以十分容易地侦测到内存的泄露。
多种定义
GDIPLUS_NO_AUTO_INIT -
GDI+在程序启动时候不会被初始化。你可以创建一个GdiPlus::GdiPlusInitialize
变量来初始化GDI+(GDI+将在析构函数调用这个变量时候被初始化)。-
GDIPLUS_USE_GDIPLUS_MEM - GdipAlloc
和GdipFree
用于内存操作。在这种情况下_Crt函数不能用于检查内存的泄露。 -
GDIPLUS_NO_AUTO_NAMESPACE -
Gdiplus名字空间将不作为一个使用的命名空间定义。所以在这种情况下你必须得使用Gdiplus::
前缀。
致谢
- http://www.codeproject.com/vcpp/gdiplus/vc6gdiplusmacro.asp
- http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp?df=100&forumid=3203&select=465515#xx465515xx
后面附带原文,望大家予以斧正!在下先谢谢了!!
GDI+ and MFC memory leak detection
Introduction
When I started to use GDI+ with MFC in VC++ 6.0 I ran into some annoying problems:
- Couldn't compile my GDI+ code with MFC without removing the DEBUG_NEW macros
- Couldn't compile GDI+ code with STL without tweaking my code
- Couldn't detect memory leaks
Here is the solution!
Here is the solution!
How to use
Include GdiplusH.h in stdafx.h:
Collapse Copy Code
// GDI+ helper file
#include "GdiplusH.h"
Features
- GDI+ will be initialized when program starts
- You can use
_CrtXXX
functions to detect memory leaks, set an allocation breakpoint, save and compare memory states, etc. - Memory leak information will be dumped to output window (MSVC IDE)
- No more compilation problem with
DEBUG_NEW
- No more compilation problem with STL
Memory leak detection
GDI+ is using GdipAlloc
and GdipFree
for allocating memory for GDI+ objects. Probably they have their own memory allocation lists in gdiplus.dll, but unfortunately there is no exported API to get any memory leak information. But GDI+ objects can be located on stack (for example: creating a local variable in a function), so there is no special initialization for these memory regions, so we do not have to use GdipAlloc
or GdipFree
. If we call the CRT debug version of memory allocation and deletion functions instead of GdipAlloc
/Free
, we can detect memory leaks very easily using the well known _CrtXXX
functions.
Miscellaneous defines
GDIPLUS_NO_AUTO_INIT -
GDI+ won't be initialized at program startup. You have to create aGdiPlus::GdiPlusInitialize
variable to initialize GDI+ (GDI+ will be uninitialized, when destructor is called for this variable).-
GDIPLUS_USE_GDIPLUS_MEM - GdipAlloc
andGdipFree
is used for memory operations. In this case _Crt functions cannot be used to detect memory leaks -
GDIPLUS_NO_AUTO_NAMESPACE -
Gdiplus namespace won't be defined as a used namespace. In this case you have to useGdiplus::
prefix.
Acknowledgements
- http://www.codeproject.com/vcpp/gdiplus/vc6gdiplusmacro.asp
- http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp?df=100&forumid=3203&select=465515#xx465515xx