看来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文档的实际含义: