我在Visual Studio 2012下的Windows上使用C ++。
我有一个开始和结束内存地址,需要生成两个地址之间的页面基址/句柄列表。我考虑过手动探测页面的可能性,但认为必须有更好的方法来枚举它们。
这种方式存在吗?
免责声明; 最终页面句柄必须是基本地址,以便在添加窗口页面大小时,生成的地址不会与下一页重叠。首选解决方案不是特定于平台的,并且与具有/不具有WOW64的32位兼容。
答案 0 :(得分:4)
VirtualQuery
几乎是你唯一的选择。它应该相当有效:
该函数确定区域中第一页的属性 然后扫描后续页面,直到它扫描整个范围 页面或直到遇到具有不匹配集的页面 属性。
所以你首先要在你关心的范围的开头调用它,然后你就会得到一大块页面。下一个调用将在该块后面开始,然后是下一个调用,依此类推。
这是一个完全未经测试的函数,它将填充MEMORY_BASIC_INFORMATION
结构数组:
int EnumVirtualAllocations(const void* ptr, size_t length, MEMORY_BASIC_INFORMATION* info, int size)
{
const void* end = (const void*)((const char*)ptr + length);
int index = 0;
while (index < size && ptr < end &&
VirtualQuery(ptr, &info[index], sizeof(*info)) == sizeof(*info))
{
MEMORY_BASIC_INFORMATION* i = &info[index];
if (i->State != MEM_FREE) index++;
ptr = (const void*)((const char*)(i->BaseAddress) + i->RegionSize);
}
return index;
}