WinCE下申请大容量物理内存

[入库:2005年8月19日] [更新:2007年3月25日]

本文简介:选择自 neo_matrix 的 blog

reference from:http://www.chinabyte.com/softchannel/72342371878043648/20040909/1852224.shtml

[文章信息]
 
作者: 付林林
时间: 2004-09-09
出处: 天极网
责任编辑: 方舟
 
[文章导读]
 
申请大容量的物理内存看起来不是难事,这里的大容量是指几十mb甚至更多的物理内存


[正文]   
 
  申请大容量的物理内存看起来不是难事。这里的大容量是指几十mb甚至更多的物理内存。对于c++程序员来说可能平时习惯了使用“new”操作符来实现。我也是这样。使用“new”非常简单,申请之后只需判断返回的指针是否是空即可。在其它的windows操作系统上的确不需要在申请大容量物理内存上过多考虑。但是在windows ce上就不同了。如果只用“new”就能搞定,那就太省事了。

 
 
  不知道windows ce下软件开发者是否遇到过这种情况,如果使用“new”申请超过30mb的物理内存,那么返回的一定是空(null),甚至程序会死锁无法响应。这其实不奇怪。在《windows ce下进程、线程和内存管理》的系列文章中我早有所言,windows ce下每个进程占有32mb的地址空间,虽然slot 1槽存放所有的非xip dll,但是我们不可能占用slot 1槽。32mb地址空间减去必要的代码段、静态数据段、默认堆和默认栈之后,所剩的地址空间少于32mb。即使程序什么都不做也无法满足超过30mb的地址空间的申请需求。所以返回为空非常正常。好在windows ce下运行的大多数软件不需要那么多的物理内存。

  感觉微软的技术不是支持到很远的将来,而是得过且过,只要满足目前的和不远的将来的需求就行。拿platform builder来说,imgram64环境变量用于支持64mb物理内存。可是没有imgram128或者imgram256甚至imgram512。可能是当时绝大多数基于windows ce的产品都没有超过64mb物理内存。现在要支持超过64mb物理内存就必须做一些修改操作。再如现在说的用“new”分配物理内存,也只是限制在32mb以内。如果想new多少就new多少,那多爽!

  “new”不行是因为地址空间不够,那我们可以采用虚拟内存分配,然后提交物理内存这种办法。理论上是这样,但是实际上还是不行。举例如下:

lpvoid g_address1, g_address2;

g_address1 = virtualalloc(0, 32 * 1024 * 1024, mem_reserve, page_noaccess);
g_address2 = virtualalloc(g_address1, 32 * 1024 * 1024, mem_commit, page_readwrite);

  上面这段代码中第一个语句是申请32mb的虚拟地址空间,函数返回一个地址说明申请是成功的。注意这个地址一定处于0x4200 0000以上(具体参见我的专栏中《windows ce下进程、线程和内存管理(三)》)。第二个语句是提交物理内存,容量为32mb。这个函数返回null,说明申请物理内存不成功。如果申请10mb、20mb的还可以。

  希望再一次破灭。最后的办法就是内存映射文件了。在windows ce的帮助文档中只提到了内存映射文件可以用来申请虚拟地址空间。可以试一试。结果证明用内存映射文件来申请大容量物理内存是可行的。内存映射文件用于多个进程共享数据时,创建内存映射的函数的第一个参数必须设置为invalid_handle_value,表示在物理内存中创建。利用这个特点我们可以申请超过32mb的物理内存。具体能够申请的大小由剩余的物理内存决定。例子如下:

#define maxlen (64*1024*1024)
handle hfile;
hfile = createfilemapping(invalid_handle_value, null, page_readwrite, 0, maxlen, null);
if(hfile == null)
{
///创建文件映射对象失败
return;
}
lpvoid lpaddress;
lpaddress = mapviewoffile(hfile, file_map_write|file_map_read, 0, 0, maxlen);
if(lpaddress == null)
{
///创建文件视图失败
return;
}

  上述的函数如果都成功了,你就可以使用物理内存了。虚拟内存的首地址是lpaddress。使用完了别忘了调用函数unmapviewoffile(lpaddress); 和closehandle(hfile);

本文关键:WinCE下申请大容量物理内存
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top