在回答有关将非连续文件块映射到连续内存here的问题时,一个受访者建议我将VirtualAllocEx()与MEM_RESERVE一起使用,以便为最终(lpBaseAddress)参数建立“安全”值对于MapViewOfFileEx()。
进一步的调查表明,此方法导致MapViewofFileEx()失败,并显示错误487:“尝试访问无效地址”。 The MSDN page says:
尽管该文档可能对有效的调用顺序而言是模棱两可的,但实验表明,使用VirtualAllocEx()为MapViewOfFileEx()保留内存是无效的。
在网上,我找到了带有硬编码值的示例-example:
#define BASE_MEM (VOID*)0x01000000
...
hMap = MapViewOfFileEx( hFile, FILE_MAP_WRITE, 0, 0, 0, BASE_MEM );
对我来说,这似乎是不充分和不可靠的...我还不清楚为什么这个地址是安全的,或者可以安全地在其中映射多少个块。鉴于我需要我的解决方案在其他分配的上下文中工作,并且我需要我的源代码在32位和64位上下文中进行编译和工作,这似乎更加不可靠。
我想知道的是,是否有任何方式来可靠地保留地址空间池,以便-随后-MapViewOfFileEx可以可靠地使用它来将块映射到显式内存地址。
最佳答案
您几乎自己一个人解决了问题,但是没有走最后一步。
如您所料,请使用VirtualAlloc
(带有MEM_RESERVE
)在您的地址空间中找到空间,但是在此之后(以及MapViewOfFileEx
之前)使用VirtualFree
(带有MEM_RELEASE
)。现在,地址范围将再次可用。然后使用与VirtualAlloc
相同的内存地址(由MapViewOfFileEx
返回)。