HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile, ...);
PVOID pvFile = MapViewOfFile(hFileMapping, ...);
// Use the memory-mapped file.
UnmapViewOfFile(pvFile);
CloseHandle(hFileMapping);
CloseHandle(hFile);
The preceding code shows the "expected" method for manipulating memory-mapped files. However, what it does not show is that the system increments the usage counts of the file object and the file-mapping object when you call MapViewOfFile. This side effect is significant because it means that we could rewrite the preceding code fragment as follows:
HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile, ...);
CloseHandle(hFile);
PVOID pvFile = MapViewOfFile(hFileMapping, ...);
CloseHandle(hFileMapping);
// Use the memory-mapped file.
UnmapViewOfFile(pvFile);
第一段代码应该是标准写法了,第二段代码有什么问题吗?标红的那句实在看不懂是啥意思。
不只是这个位置
《windows核心编程》很多地方都有提醒读者CloseHandle并没有关闭对象
只是影响引用计数
(嗯……,至少第二段代码所示的调用顺序是没问题的)
HANDLE hFileMapping = CreateFileMappingW(hFile,0,PAGE_READONLY,0,0,0);
PVOID pvFile = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);printf("%x,%x,%x,%p\n",GetCurrentProcessId(),hFile,hFileMapping,pvFile);
getchar();
CloseHandle(hFileMapping);
CloseHandle(hFile);
puts("closed");
getchar();
getchar();
UnmapViewOfFile(pvFile);执行closehandle之前的对象状况
lkd> .process 8997a5d0
Implicit process is now 8997a5d0
lkd> !handle 30PROCESS 8997a5d0 SessionId: 0 Cid: 05a4 Peb: 7ffdd000 ParentCid: 055c
DirBase: 0a3c0280 ObjectTable: e187cd40 HandleCount: 13.
Image: cbtest.exeHandle table at e1f85000 with 13 entries in use0030: Object: 89937540 GrantedAccess: 00120089 Entry: e1f85060
Object: 89937540 Type: (89a16040) File
ObjectHeader: 89937528 (old version)
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \Downloads\fg.ini {HarddiskVolume2}
lkd> !object 89937540
Object: 89937540 Type: (89a16040) File
ObjectHeader: 89937528 (old version)
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \Downloads\fg.ini {HarddiskVolume2}
lkd> !handle 34PROCESS 8997a5d0 SessionId: 0 Cid: 05a4 Peb: 7ffdd000 ParentCid: 055c
DirBase: 0a3c0280 ObjectTable: e187cd40 HandleCount: 13.
Image: cbtest.exeHandle table at e1f85000 with 13 entries in use0034: Object: e196e240 GrantedAccess: 000f0005 Entry: e1f85068
Object: e196e240 Type: (89a25040) Section
ObjectHeader: e196e228 (old version)
HandleCount: 1 PointerCount: 1
lkd> !object e196e240
Object: e196e240 Type: (89a25040) Section
ObjectHeader: e196e228 (old version)
HandleCount: 1 PointerCount: 1
执行close之后的对象状况
lkd> !object 89937540
Object: 89937540 Type: (bad0b0b0)
ObjectHeader: 89937528 (old version)
HandleCount: 0 PointerCount: 0
lkd> !object e196e240
Object: e196e240 Type: (bad0b0b0)
ObjectHeader: e196e228 (old version)
HandleCount: 0 PointerCount: 0
说明view并不需要文件对象和section对象的存在
由于其他程序的影响,文件对象和节对象可能存在,但不能保证
它们的关系见windows internals 5如果仅仅是同一个进程用这些,当然没问题,但如果涉及到进程间通信,则必须予以考虑
下面的代码的OpenFileMapping不会成功,第二个CreateFileMapping得到的和第一个内容独立,如果这样的代码用于IPC则会与预料的不同HANDLE sec=CreateFileMappingW((HANDLE)-1,0,PAGE_READWRITE,0,64,L"sec");
printf("%x\n",sec);
PVOID view = MapViewOfFile(sec,FILE_MAP_READ,0,0,0);
printf("%p\n",view);
CloseHandle(sec);
HANDLE sec2=OpenFileMappingW(FILE_MAP_WRITE,0,L"sec");
HANDLE sec3=CreateFileMappingW((HANDLE)-1,0,PAGE_READWRITE,0,64,L"sec");
printf("%x",sec2);
(都看不懂啊……)
pointerCount 和 HandleCount 哪一个才是引用计数呢?不是说MapViewOfFile会增加引用计数吗?那么为什么这两个值都为1呢?
只有pointercount=0才可能释放掉对象
这句话可以忘掉