我正在研究 Windows 上的内存映射并编写了以下代码(为了便于阅读,我从副本中省略了错误处理):
HANDLE file_h = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE map_h = CreateFileMapping(file_h, NULL, PAGE_READWRITE, 0, lengthOfFile + padding, NULL);
char * map;
map = MapViewOfFile(map_h, FILE_MAP_COPY, 0, 0, lengthOfFile + padding);
其中lengthOfFile是我之前以这种方式计算的文件的长度(由于某些与这种情况无关的原因):
FILE * file;
file = fopen(filename,"rb");
fseek(file, 0, SEEK_END);
int lengthOfFile = ftell(file);
fseek(file, 0, SEEK_SET);
int last = (lengthOfFile % 4);
int n_pack = (int)(lengthOfFile / 4);
int padding = 4 - last;
并且填充是我需要添加的一些额外长度(您可以通过阅读上面的代码找出原因)。
之后,我对内存映射文件执行一些操作,这些操作涉及到它的修改以及将它的新值分配给另一个函数。
我怎样才能做到这一点,以便当我关闭file_h和map_h处理源文件(文件名)时保持不变(现在,一旦我关闭它的句柄,它就会被修改,因为那个额外的填充显然被“刷新”到句柄关闭后的源文件)?
我尝试将PAGE_WRITECOPY标志与PAGE_READWRITE(需要修改内存映射文件的内容)一起使用,但CreateFileMapping函数无法返回ERROR_INVALID_PARAMETER (87) 错误。
换句话说,我需要实现在 Unix 中使用的相同行为:
mmap(0,lengthOfFile + padding,PROT_READ | PROT_WRITE, **MAP_PRIVATE**,fileno(file),0);
我猜关键点是MAP_PRIVATE属性。