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

如图:

1

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

查找Gdiplus::Bitmap类定义:

2

发现定义并没有变,是可以接受三个参数的,奇怪。。。偶尔鼠标滑过 gdiplusheaders.h,发现其所在的SDK是来自

C:\Program Files (x86)\Windows Kits\8.1\Include\um\gdiplusheaders.h。难道引用的SDK 是8.1的不可以? 尝试改变

SDK的引用,vs2015修改项目属性--》常规--》改成 windows10 版本的SDK,如图:

3

再返回编译,结果还是没变,错误依旧。

把鼠标放到标有红色底线的 new ,仔细查看错误提示:发现有句 define new DEBUG_NEW,难道是这个预处理宏的

原因?全局搜索,发现MFC在debug模式下定义了这个预处理宏,擦,扎到原因了。。。。如图:

4

这个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+的头文件或创建一个包装类,这通常不推荐,因为它涉及到对第三方库的修改,

可能会影响库的维护和升级。

posted on 2026-01-09 11:02  FilexHu  阅读(2)  评论(0)    收藏  举报