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_EXECUTE_READ、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
要开始视图的文件偏移量
[in] dwNumberOfBytesToMap
要映射到视图的文件映射的字节数。 所有字节必须位于 CreateFileMapping指定的最大大小内。 如果此参数为 0(零),则映射从指定的偏移量扩展到文件映射的末尾。
[in, optional] lpBaseAddress
指向调用进程地址空间中开始映射的内存地址的指针。 这必须是系统的内存分配粒度的倍数,或者函数失败。 若要确定系统的内存分配粒度,请使用 GetSystemInfo 函数。 如果指定地址处没有足够的地址空间,函数将失败。
如果 lpBaseAddressNULL,则操作系统会选择映射地址。 在此方案中,该函数等效于 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) | 是的 |
群集共享卷文件系统 (CsvFS) | 是的 |
可复原文件系统 (ReFS) | 是的 |
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [仅限桌面应用] |
支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | memoryapi.h (包括 Windows.h、Memoryapi.h) |
库 | onecore.lib |
DLL | Kernel32.dll |