这个限制使得要我们要知道Windows CE如何对栈管理。当线程被建立的时候,Windows CE保留一个64-KB的区域给每个线程的栈。栈增加时,提交虚拟内存页是从上至下的。当栈减小时,系统将处于的低内存环境(low-memory),会回收在栈下面未使用但是仍然被提交的页。58KB的限制来源于64-KB的区域减去用来防止栈的上溢和下溢的页面数量。
静态数据
列表7-1。映象文件的顶部显示了应用程序数据段的大小
memtest
Timestamp is 34ce4088 (Tue Jan 27 12:16:08 1998)
Preferred load address is 00010000
Start Length Name Class
0001:00000000 00006100H .text CODE
0002:00000000 00000310H .rdata DATA
0002:00000310 00000014H .xdata DATA
0002:00000324 00000028H .idata$2 DATA
0002:0000034c 00000014H .idata$3 DATA
0002:00000360 000000f4H .idata$4 DATA
0002:00000454 000003eeH .idata$6 DATA
0002:00000842 00000000H .edata DATA
0003:00000000 000000f4H .idata$5 DATA
0003:000000f4 00000004H .CRT$XCA DATA
0003:000000f8 00000004H .CRT$XCZ DATA
0003:000000fc 00000004H .CRT$XIA DATA
0003:00000100 00000004H .CRT$XIZ DATA
0003:00000104 00000004H .CRT$XPA DATA
0003:00000108 00000004H .CRT$XPZ DATA
0003:0000010c 00000004H .CRT$XTA DATA
0003:00000110 00000004H .CRT$XTZ DATA
0003:00000114 000011e8H .data DATA
0003:000012fc 0000108cH .bss DATA
0004:00000000 000003e8H .pdata DATA
0005:00000000 000000f0H .rsrc$01 DATA
0005:000000f0 00000334H .rsrc$02 DATA
Address Publics by Value Rva+Base Lib:Object
0001:00000000 _WinMain 00011000 f memtest.obj
0001:0000007c _InitApp 0001107c f memtest.obj
0001:000000d4 _InitInstance 000110d4 f memtest.obj
0001:00000164 _TermInstance 00011164 f memtest.obj
0001:00000248 _MainWndProc 00011248 f memtest.obj
0001:000002b0 _GetFixedEquiv 000112b0 f memtest.obj
0001:00000350 _DoCreateMain 00011350 f memtest.obj.
在列表7-1中的映象文件指出了EXE文件有五个区。区0001是文本段,包含程序中可执行的代码。区0002包含只读(read-only)静态数据。区0003包含可读写(read/write)静态数据。区0004包含调用其他DLL的固定表。最后,区0005是资源区,包含应用程序的资源,例如菜单和对话框模板。
让我们来看看.data,.bss和.rdata行。.data区包含已初始化的可读写数据。如果你这样初始化了一个全局变量:
static
HINST
g_hLoadlib
=
NULL;
g_loadlib
变量将结束在.data
段末尾。.bss
段包含未初始化的可读写数据。一个缓冲被定义如下:
static
BYTE
g_ucItems[256];
以.bss段为结尾。最后一个段.rdata,包含只读数据。你使用const关键字定义的静态数据结束在.rdata段。有一个结构的例子,使我用来作消息查询表的:
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
};
字符串资源
有一个经常忘记的只读区域时应用程序的资源段,像我前面在第四章提到的Windows CE的新特性有一个
LoadString
函数,值得再次重复。如果你调用LoadString
时指向缓冲区的指针写0
,函数将返回一个指向资源段中字符串的指针。例子如下:
LPCTSTR pString;
pString = (LPCTSTR)LoadString (hInst, ID_STRING, NULL, 0)
返回的字符串是只读的,但是它允许你应用字符串而不需要分配一个缓冲给字符串。这里警告一下,字符串不能以
0结尾,除非你在资源编译器命令行中加了-n开关。不管如何,单词必须是先于字符串资源长度(译者注:作者此处意思可能是说长度包含字符串资源的长度)。
选择适当的内存类型