调用 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 只能被用在共享内存文件视图中。