MapViewOfFileEx 函数 (memoryapi.h)
将映射的文件视图映射到调用进程的地址空间中。 调用方可以选择为视图指定建议的基内存地址。
若要指定物理内存的 NUMA 节点,请参阅 MapViewOfFileExNuma。
语法
LPVOID MapViewOfFileEx(
[in] HANDLE hFileMappingObject,
[in] DWORD dwDesiredAccess,
[in] DWORD dwFileOffsetHigh,
[in] DWORD dwFileOffsetLow,
[in] SIZE_T dwNumberOfBytesToMap,
[in, optional] LPVOID lpBaseAddress
);
参数
[in] hFileMappingObject
文件映射对象的句柄。 CreateFileMapping 和 OpenFileMapping 函数返回此句柄。
[in] dwDesiredAccess
对文件映射对象的访问类型,该对象确定页面的页面保护。 此参数可以是以下值之一,也可以是多个值的按位 OR 组合(如果适用)。
使用按位 OR,可以将上述值与这些值组合在一起。
值 | 含义 |
---|---|
|
映射文件的写入时复制视图。 文件映射对象必须已使用 PAGE_READONLY、 PAGE_READ_EXECUTE、 PAGE_WRITECOPY、 PAGE_EXECUTE_WRITECOPY、 PAGE_READWRITE或 PAGE_EXECUTE_READWRITE 保护创建。
当进程写入写入时复制页时,系统会将原始页面复制到进程专用的新页。 新页面由分页文件提供支持。 对新页面的保护从写入时复制更改为读/写。 指定写入时复制访问权限时,系统将和进程提交费用用于整个视图,因为调用进程可能会写入视图中的每一页,从而使所有页面都成为私有页面。 新页面的内容永远不会写回到原始文件,并在取消映射视图时丢失。 |
|
从 Windows 10 版本 1703 开始,此标志指定应使用大页面支持映射视图。 视图的大小必须是 GetLargePageMinimum 函数报告的大型页面大小的倍数,并且文件映射对象必须已使用 SEC_LARGE_PAGES 选项创建。 如果为 lpBaseAddress 提供非 null 值,则该值必须是 GetLargePageMinimum 的倍数。 |
|
映射文件的可执行视图 (映射的内存可以作为代码) 运行。 创建文件映射对象时必须具有 PAGE_EXECUTE_READ、 PAGE_EXECUTE_WRITECOPY或 PAGE_EXECUTE_READWRITE 保护。
Windows Server 2003 和 Windows XP: 此值从 Windows XP SP2 和 Windows Server 2003 SP1 开始可用。 |
|
将映射文件中的所有位置设置为控制流防护 (CFG) 的无效目标。 此标志类似于 PAGE_TARGETS_INVALID。 将此标志与执行访问权限 FILE_MAP_EXECUTE结合使用。 对这些页面中的位置的任何间接调用都将失败 CFG 检查,并且进程将终止。 分配的可执行页面的默认行为是标记为 CFG 的有效调用目标。 |
对于使用 SEC_IMAGE 属性创建的文件映射对象, dwDesiredAccess 参数不起作用,应设置为任何有效值,例如 FILE_MAP_READ。
有关访问文件映射对象的详细信息,请参阅 文件映射安全性和访问权限。
[in] dwFileOffsetHigh
视图开始位置的文件偏移量的高阶 DWORD 。
[in] dwFileOffsetLow
视图开始位置的文件偏移量的低序 DWORD 。 高偏移量和低偏移量的组合必须在文件映射中指定偏移量。 它们还必须与系统的内存分配粒度匹配。 也就是说,偏移量必须是分配粒度的倍数。 若要获取系统的内存分配粒度,请使用 GetSystemInfo 函数,该函数填充 SYSTEM_INFO 结构的成员。
[in] dwNumberOfBytesToMap
要映射到视图的文件映射的字节数。 所有字节都必须在 CreateFileMapping 指定的最大大小内。 如果此参数为 0 (零) ,则映射将从指定的偏移量扩展到文件映射的末尾。
[in, optional] lpBaseAddress
指向调用进程地址空间中映射开始位置的内存地址的指针。 这必须是系统内存分配粒度的倍数,否则函数将失败。 若要确定系统的内存分配粒度,请使用 GetSystemInfo 函数。 如果指定地址上没有足够的地址空间,则函数将失败。
如果 lpBaseAddress 为 NULL,则操作系统会选择映射地址。 在此方案中, 函数等效于 MapViewOfFile 函数。
虽然可以指定现在 (操作系统) 不使用的安全地址,但不能保证该地址随时间推移保持安全。 因此,最好让操作系统选择地址。 在这种情况下,不会将指针存储在内存映射文件中,而应存储与文件映射基的偏移量,以便可以在任何地址使用映射。
返回值
如果函数成功,则返回值为映射视图的起始地址。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
注解
映射文件会使文件的指定部分在调用进程的地址空间中可见。
对于大于地址空间的文件,一次只能映射一小部分文件数据。 第一个视图完成后,取消映射该视图并映射新视图。
若要获取视图的大小,请使用 VirtualQueryEx 函数。
页面文件支持的文件映射对象中页面的初始内容为 0 (零) 。
通常,建议的地址用于指定文件应映射到多个进程中的同一地址。 这要求地址空间区域在所有涉及的进程中都可用。 不能在用于映射的区域进行其他内存分配,包括使用 VirtualAlloc 或 VirtualAllocEx 函数来保留内存。
如果 lpBaseAddress 参数指定基偏移量,则当调用进程尚未使用指定的内存区域时,函数将成功。 系统不确保同一内存区域可用于其他 32 位进程中的内存映射文件。
文件 (或文件映射对象的多个视图及其映射文件) 如果它们在指定时间包含相同的数据,则它们是 一致的 。 如果文件视图派生自同一个文件映射对象,则会发生此情况。 进程可以使用 DuplicateHandle 函数将文件映射对象句柄复制到另一个进程中,或者另一个进程可以使用 OpenFileMapping 函数按名称打开文件映射对象。
有一个重要例外,从同一文件支持的任何文件映射对象派生的文件视图在特定时间是一致的或相同的。 对于进程内的视图以及由不同进程映射的视图,可以保证一致性。
异常与远程文件相关。 尽管 MapViewOfFileEx 适用于远程文件,但它不会使它们保持一致。 例如,如果两台计算机都将一个文件映射为可写文件,并且都更改了同一页,则每台计算机只能看到自己对页面的写入。 在磁盘上更新数据时,不会合并数据。
不保证文件的映射视图与 ReadFile 或 WriteFile 函数访问的文件一致。
若要防止 EXCEPTION_IN_PAGE_ERROR 异常,请使用结构化异常处理来保护写入或读取除页面文件以外的文件的内存映射视图的任何代码。 有关详细信息,请参阅 从文件视图中读取和写入。
通过映射视图修改文件时,上次修改时间戳可能不会自动更新。 如果需要,调用方应使用 SetFileTime 设置时间戳。
若要拥有具有可执行权限的文件,应用程序必须使用 PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_READ 调用 CreateFileMapping,然后使用 FILE_MAP_EXECUTE FILE_MAP_WRITE | 或 FILE_MAP_EXECUTE | FILE_MAP_READ 调用 MapViewOfFileEx。
在 Windows Server 2012 中,以下技术支持此函数。
技术 | 支持 |
---|---|
服务器消息块 (SMB) 3.0 协议 | 是 |
SMB 3.0 透明故障转移 (TFO) | 是 |
具有横向扩展文件共享的 SMB 3.0 (SO) | 是 |
群集共享卷文件系统 (CSV) | 是 |
弹性文件系统 (ReFS) | 是 |
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | memoryapi.h (包括 Windows.h、Memoryapi.h) |
Library | onecore.lib |
DLL | Kernel32.dll |