看来MapViewOfFile增加了文件映射内核对象的引用计数。

引用MSDN对 MapViewOfFile 的描述:



同样,从Windows通过C/C++,第5版:



尽管有这些,但我的实际测试却显示出相反的结果。我在Windows 10 64位上使用Visual Studio 2015。测试程序如下:

#include <windows.h>

int main() {
  HANDLE h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 128, "test");
  void* p_memory = MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, 0);
  CloseHandle(h);
  h = OpenFileMappingA(FILE_MAP_WRITE, FALSE, "test");
  DWORD dw = GetLastError(); // ERROR_FILE_NOT_FOUND
}
OpenFileMapping调用失败,出现最后一个错误ERROR_FILE_NOT_FOUND。当我删除CloseHandle调用时,一切都会好起来的。这意味着CloseHandle调用消除了文件映射内核对象的最后一个引用计数并将其销毁。这又意味着MapViewOfFile实际上不会增加​​对象的引用计数。

我想确定正在发生什么,以及相对于文件映射内核对象的引用计数,MapViewOfFile的确切语义是什么。

最佳答案

通过使用文件作为后备存储而不是页面文件,可以使其更具说服力:

int main() {
    const char* path = "mmf.bin";
    DeleteFile(path);
    HANDLE hFile = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
        FILE_FLAG_DELETE_ON_CLOSE,
        NULL, CREATE_NEW, 0, NULL);
    HANDLE h = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, 128, "test");
    int* p_memory = (int*)MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, 128);
    CloseHandle(h);
    DWORD attr = GetFileAttributes(path);
    if (attr != INVALID_FILE_ATTRIBUTES) puts("File still exists");
    else puts("File is gone");
}

输出:文件不见了

因此,“系统增加文件对象的使用计数”绝对是不正确的。而且我认为您不赞成这样做会增加文件映射对象的使用计数。不知道该怎么做,Richter不会经常出错。这本书的勘误表也没有。在早期版本的Windows中,它可能以这种方式工作,所以不确定,因为我从来没有故意出错。我们必须坚持SDK文档的实际含义:

10-04 12:33