好久没更新博客了,今天偶尔手痒想重温下GDI+,结果Gdiplus::Bitmap创建新位图使用new操作符来动态分配内存时,发生一个错误。
如图:

编译错误提示:“gdiplus::gdiplusbase::operator new”: 函数不接受 3 个参数”。这不可能啊,难道我记错了?打开gdiplusheaders.h
查找Gdiplus::Bitmap类定义:

发现定义并没有变,是可以接受三个参数的,奇怪。。。偶尔鼠标滑过 gdiplusheaders.h,发现其所在的SDK是来自
C:\Program Files (x86)\Windows Kits\8.1\Include\um\gdiplusheaders.h。难道引用的SDK 是8.1的不可以? 尝试改变
SDK的引用,vs2015修改项目属性--》常规--》改成 windows10 版本的SDK,如图:

再返回编译,结果还是没变,错误依旧。
把鼠标放到标有红色底线的 new ,仔细查看错误提示:发现有句 define new DEBUG_NEW,难道是这个预处理宏的
原因?全局搜索,发现MFC在debug模式下定义了这个预处理宏,擦,扎到原因了。。。。如图:

这个DEBUG_NEW预处理宏,将new操作符扩展为一个接受额外两个参数(源文件名和代码行号)的重载版本,以便
在调试时帮助跟踪内存分配和泄漏。然而,GDI+库并没有为new操作符提供接受这三个参数的重载版本,因此会导致编译错误。
解决方案:
1.简单方法 就是注释掉MFC的DEBUG_NEW定义
//#ifdef _DEBUG
//#define new DEBUG_NEW
//#endif
这样就不会在Debug模式下对new操作符进行扩展。但这样做会失去MFC提供的内存泄漏检测功能。
2.使用全局作用域的new操作符
为了保持MFC的内存泄漏检测功能,同时又能避免编译错误,可以在创建GDI+对象时使用全局作用域的new操作符。
通过在new关键字前加上全局作用域运算符::,可以明确指定使用全局的new操作符,而不是MFC重载的版本。
Gdiplus::Bitmap* pBitmap = ::new Gdiplus::Bitmap(cx, cy, PixelFormat32bppRGB);
3.为GDI+实现自定义的new和delete操作符
另一种解决方案是为GDI+的类实现自定义的new和delete操作符,这些操作符可以接受MFC重载的new操作符所需的额外参数,
但忽略它们。这种方法需要修改GDI+的头文件或创建一个包装类,这通常不推荐,因为它涉及到对第三方库的修改,
可能会影响库的维护和升级。
本文来自博客园,作者:FilexHu,转载请注明原文链接:https://www.cnblogs.com/filexhu/p/19460419
浙公网安备 33010602011771号