CreateCompatibleBitmap返回错误码8的原因及解决方案
来源:互联网 发布:淘宝seo视频教程 编辑:程序博客网 时间:2024/05/21 19:45
转自:http://hi.baidu.com/li_kun_peng/item/785d84f5ec21014c932af2b2
最近测试程序,发现一个图片显示程序在一台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, 0, sizeof(BITMAPINFOHEADER));
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, 0, sizeof(BITMAPINFO));
bmi.bmiHeader = bmih;
void* p;
hBitmap = ::CreateDIBSection(cdc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, &p, NULL, 0);
- CreateCompatibleBitmap返回错误码8的原因及解决方案
- CreateCompatibleBitmap的GetLastError返回错误码8的原因及解决方案
- 搭建网站常见返回码40X 50X等错误的原因及解决方案
- java.lang.UnsupportedClassVersionError错误的原因及解决方案
- 关于IE6中absolute定位错误的原因及解决方案
- java.lang.UnsupportedClassVersionError错误的原因及解决方案
- Android 加载 SO 库 UnsatisfiedLinkError 错误的原因及解决方案
- java.lang.NoClassDefFoundError错误产生的原因及解决方案
- 调用 RegLoadKey 失败,返回错误码1314的原因及解决办法
- (从“C://Program Files//Microsoft Visual Studio 8//VC//bin//cl.exe”返回) 错误的原因及解决办法
- UpdateLayeredWindow返回317错误的原因
- UnsatisfiedLinkError错误的原因以及解决方案
- KindEditor文件上传js拒绝访问错误的原因及解决方案
- android编写UI出现error: Error parsing XML: unbound prefix 的错误原因及解决方案
- String内存溢出异常(错误)可能的原因及解决方案
- android编译时报错:Error parsing XML: unbound prefix 的错误原因及解决方案
- WordPress媒体库图片不显示或显示错误的原因及解决方案
- 【mysql 服务启动失败,报 1067 错误】 的可能原因及解决方案
- Fibnacci..放草稿箱里。。愣是忘了、、、
- 第十二周上机任务——项目5——特殊三位数
- 学习使用JQuery来制作一个动态表格
- 为什么不能通过优化RMSE得到Top-K Recommendations?
- ios检查网络连接
- CreateCompatibleBitmap返回错误码8的原因及解决方案
- 使用内存映射文件在进程之间共享数据
- 求一个数的二进制
- 练习体验运算结果
- 汉诺塔-算法
- 回车和换行
- fork要做的事情与不需要做的事情
- Verilog HDL Syntax And Semantics Part-II
- Opencv2.4.3 在Win64下VS2010配置