调用 CreateViewStream () 时 access 参数不能为 Write 的坑
当为 IPC 调用使用 MemoryMappedFile.CreateNew()
方法创建共享内存时,其可访问性级别至少要设置为 MemoryMappedFileAccess.ReadWrite
,但是,当调用 MemoryMappedFile.CreateViewStream(long offset, long size, MemoryMappedFileAccess access)
为共享内存创建流的时候,却不能将 access
的可访问性设置为 MemoryMappedFileAccess.Write
,而必须设置为 MemoryMappedFileAccess.ReadWrite
,这一点在 MSDN 中并没有明确指明,但是 MemoryMappedFileAccess
的注释中却说当创建 View 的时候 Write
级别是可以被设置的:
1 | // This enum maps to both the PAGE_XXX and FILE_MAP_XXX native macro definitions. |
在 CreateViewStream()
方法中检查过可访问性之后,会调用 CreateView()
来尝试获得句柄:
1 | [ ] |
随后,在 CreateView()
中巨硬帮我们进行了内存页对齐,32 位长整数指针判断,请求空间可用判断巴拉巴拉的,由于我们申请的内存大小可能小于物理内存大小,部分内容会被放在分页文件里,为了保证 View 的可用性和一致性,用到了 VirtualAlloc()
将参数设置为 MEM_COMMIT
来返回 “提交” 的内存指针,并且使用 GetPageAccess()
来将 MemoryMappedFileAccess
转换为 flProtect
。
但是,在内存可访问性常量中,并没有能与 “只写 (write-only)” 相对应的可访问性级别,也就是说,注释里的:
This enum maps to both the PAGE_XXX and FILE_MAP_XXX native macro definitions.
并不是和实际情况一样,Write
只能被用在共享内存文件视图中。