资源预览内容
亲,该文档总共2页全部预览完了,如果喜欢就下载吧!
资源描述
CreateCompatibleBitmap返回错误码8 的原因及解决方案最近测试程序, 发现一个图片显示程序在一台512M 内存的机器上同时打开5 个以后,就无法显示图片了。在网上查了一下,CSDN 有袁峰回答了一个类似问题。根据袁峰的提示,我找了他的书Windows 图形编程(英文名: Windows Graphics Programming Win32 GDL and DirectDraw),借鉴他的源代码,很快解决了问题。现在回过头来总结一下我程序问题的解决过程。我的绘图程序用的是DDB ,创建 bitmap 的时候用的CreateCompatibleBitmap。这个函数的好处是简单,好调用,而且可以创建与显示设备兼容的位图。在测试程序的时候,发现运行五个程序实例后,从第六个开始就无法显示图片了。跟踪调试一下,发现是调CreateCompatibleBitmap出错, GetLastError返回错误码为 8,意思是没内存了。在我的程序无法显示图片时,用mspaint.exe画图程序却还能打开。问题比较明显了,肯定是我的程序有问题,不够完善。上网一查,有人说是没有合理释放Create 的 GDI 对象,导致GDI 句柄超限或内存泄漏。可用任务管理器查看 GDI 对象和内存, 发现我的程序占用的内存和GDI 对象句柄都不高,都远低于画图程序。可画图程序偏偏就基本可以无休止地打开任意多个实例并显示图片。再在网上找,在CSDN 发现了袁峰前辈针对类似问题的回帖,真是一语道破天机,真乃高人也!问题的本质在于我调用CreateCompatibleBitmap创建 DDB 位图。 此函数创建位图时用的是系统内核的分页内存,这是稀有资源。我要显示的图片3000 多 3000 多,24dpp ,粗算一下要30 多兆内存。在运行我程序的时候,我打开任务管理器的性能页,通过“ 核心内存 ” 查看程序打开前后分页内存数的变化。结果真是每运行一个程序实例,分页内存数就增加30 多兆。运行第五个的时候,由于系统无法再分配出30 多兆分页内存了,所以调用CreateCompatibleBitmap就不能成功。问题发现了, 如何解决呢?还是袁前辈给出了办法,就是用 CreateDIBSection创建位图。 刚好手头有一本袁前辈的 Windows 图形编程,阅读了第10 章的部分小节,参考了随书光盘中的部分代码,很快就解决了问题。 CreateDIBSection的好处是,它使用虚拟内存创建位图。这样运行程序的实例数就只限于pagefile 和磁盘空间大小了。不过CreateDIBSection比 CreateCompatibleBitmap要难调用一些。当然,有袁前辈的示例代码就很简单了。我并不是要专于GDI 编程,只是偶然间需要实现一个显示照片的程序。如果不是袁前辈的回帖、书籍和示例代码,我真不知道要花多少时间才能找到问题并解决之。所以,真的要感谢袁前辈!袁前辈本科毕业于上海大学,研究生在南京大学读,获得了硕士和博士学位。Windows 图形编程一书很有深度,非国内同类著作所能比拟,让人敬佩!使用 CreateCompatibleBitmap创建位图的时候,返回错误码8:存储空间不足,无法处理此命令。原因:此函数创建位图时用的是系统内核的分页内存,这是稀有资源(可从任务管理器性能页的核心内存项查看),因此,如果位图比较大的话,就报错了。解决方案: CreateDIBSection。这个函数不再从系统内核的分页内存中获取资源了,而是从物理内存和虚拟内存中获取,因此,原则上对位图的大小限制要小得多。附上一小段 CreateDIBSection的用法示例:BITMAPINFOHEADER bmih; memset( bmih.biSize = sizeof(BITMAPINFOHEADER); bmih.biBitCount = 24; bmih.biCompression = BI_RGB; bmih.biPlanes = 1; bmih.biWidth = info.nImageWidth; bmih.biHeight = info.nImageHeight; BITMAPINFO bmi; memset( bmi.bmiHeader = bmih; void* p; hBitmap = :CreateDIBSection(cdc.GetSafeHdc(),
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号