通过CreateFileMapping实现内存共享(Memory sharing through createfilemapping)

转载:https://www.cnblogs.com/hrhguanli/p/4007100.html

1. 用途和基本操作用于不同进程之间的内存共享操作, 能够将一个物理文件映射到内存其中然后直接利用分配到的或者打开的命名共享内存的地址空间实现资源共享訪问

2. 相关流程1) 新建命名共享内存首先利用CreateFile或者CreateFileForMapping获得一个用于映射的物理文件句柄, 然后利用该文件句柄结合CreateFileMapping得到一个命名的共享内存映射文件句柄。

//CreateFileMapping 为指定文件创建一个有名或无名的文件映象;
HANDLE CreateFileMapping(
  HANDLE hFile,              // 映射文件的句柄
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 安全描写叙述符指针
  DWORD flProtect,           // 对映射对象的保护
  DWORD dwMaximumSizeHigh,   // 对象最大长度的高32位
  DWORD dwMaximumSizeLow,    // 对象最大长度的低32位
  LPCTSTR lpName             // 文件内存映射对象的名字
);

注意:hFile:映射文件的句柄,文件的打开模式必须与flProtect參数指定的相一致;假设这个參数值为0xFFFFFFFF,那么必须在dwMaximumSizeHigh和dwMaximumSizeLow參数中指定映射对象的大小。而且将在操作系统虚拟内存页面替换文件里创建文件映射对象,而不是使用磁盘文件,同一时候必须给出这个映射对象的大小。文件映射对象通过副本,遗传或名字来共享。lpFileMappingAttributes:安全描写叙述符指针,决定返回句柄能否被子进程继承,假设是NULL,那么子进程不能继承。WinNt中,假设是NULL,那么文件映射对象得到一个默认的安全描写叙述符。flProtect:为得到的文件试图指定保护模式,能够被设置为下列值: PAGE_READONLY :仅仅读属性,而且hFile相应的文件必须以GENERIC_READ形式打开。 PAGE_READWRITE:可读可写属性,而且hFile相应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。 PAGE_WRITECOPY:对可写区域复制后操作,而且hFile相应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。dwMaximumSizeHigh,dwMaximumSizeLow:假设这两个參数为0,则文件映射对象的最大长度等于hFile指定的文件长度。lpName:文件映射对象的名字,假设这个名字已存在,则依照flProtect指定的来处理映射对象。假设此參数为空,则创建一个无名字的文件映射对象。假设此參数的名字与系统事件的名字同样,则函数运行失败,GetLastError返回 ERROR_INVALID_HANDLE;

返回值:函数调用成功返回文件映射对象的句柄,假设文件映射对象已经存在则返回原有映射对象的句柄,GetLastError返回ERROR_ALREADY_EXISTS。函数运行失败返回Null。

2) 打开命名共享内存假设须要共享已经存在的命名共享内存映射文件, 使用OpenFileMapping函数。//OpenFileMapping 打开一个已命名的文件映射对象

HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // 訪问模式
  BOOL bInheritHandle,    // 继承标志
  LPCTSTR lpName          // 文件映射对象名指针
);

注意:dwDesiredAccess:訪问模式与MapViewOfFile中的訪问模式同样。bInheritHandle:继承标志,能否够被一个新的进程继承使用,假设为TRUE,就能够被一个新进程继承句柄。返回值: 成功返回一个已命名的文件映射对象,失败返回NULL。

3) 获得地址空间指针进行内存映射文件的读写和一般的文件读写不同, 是直接面对你申请的地址空间, 为此须要使用MapViewOfFile得到相关的地址LPVOID类型的指针。假设须要进行文件写入, 能够通过类型转换直接对于内存地址进行赋值, 比方:memcpy( lpAddress, lpBuf, ….)这里自然须要防止内存溢出的情况。假设是读取操作,将參数顺序调整一下就能够了。

MapViewOfFile 在调用进程的地址空间映射一个文件视图
LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,  // 已创建的文件映射对象句柄
  DWORD dwDesiredAccess,      // 訪问模式
  DWORD dwFileOffsetHigh,     // 文件偏移的高32位
  DWORD dwFileOffsetLow,      // 文件偏移的低32位
  DWORD dwNumberOfBytesToMap  // 映射视图的大小
);

注意:hFileMappingObject: 由CreateFileMapping 或 OpenFileMapping 返回的文件映射对象句柄。dwDesiredAccess:映射视图的訪问模式,与创建文件映射对象的保护模式flProtect有关,能够被设置为下列值: FILE_MAP_WRITE:一个可读写属性的文件视图被创建,保护模式为PAGE_READWRITE FILE_MAP_READ :一个仅仅读属性的文件视图被创建,保护模式为PAGE_READWRITE 或 PAGE_READONLY FILE_MAP_ALL_ACCESS:与FILE_MAP_WRITE模式同样 FILE_MAP_COPY:保护模式为PAGE_WRITECOPY时,得到一个视图文件,当你对视图文件写操作时,页面自己主动交换,而且你所做的改动不会损坏原始数据资料。dwNumberOfBytesToMap:映射文件部分的大小,假设为0,则映射整个文件。返回值:假设成功返回返回映射视图的起始地址,假设失败返回NULL。

4)MapViewOfFileEx 在调用进程的地址空间映射一个文件视图,而且同意调用进程为映射视图指定特殊的内存地址

LPVOID MapViewOfFileEx(
  HANDLE hFileMappingObject,  // 文件映射对象的句柄
  DWORD dwDesiredAccess,      // 訪问模式
  DWORD dwFileOffsetHigh,     // 文件偏移的高32位
  DWORD dwFileOffsetLow,      // 文件偏移的低32位
  DWORD dwNumberOfBytesToMap, // 映射视图的大小
  LPVOID lpBaseAddress        // 指定映射视图的事实上内存地址
);

注意:与MapViewOfFile使用方法同样,可是假设指定的内存地址空间大小不够,则函数运行失败。

5) 将内存拷贝到所映射的物理文件上面FlushMapViewOfFile函数能够将内存里面的内容DUMP到物理磁盘上面FlushViewOfFile 把文件映射视图中的改动的内容或所有写回到磁盘文件里

BOOL FlushViewOfFile(
  LPCVOID lpBaseAddress,       // 改动内容的起始地址
  DWORD dwNumberOfBytesToFlush // 改动的字节数目
);

函数运行成功返回非零。

6) 卸载内存映射文件地址指针UnmapViewOffFile函数就是卸载UnmapViewOfFile 删除文件的映射视图

BOOL UnmapViewOfFile(
  LPCVOID lpBaseAddress   // 映射视图起始地址
);

注意:lpBaseAddress:映射视图起始地址,由 MapViewOfFile 函数 MapViewOfFileEx产生。返回值:假设调用成功返回非零,而且全部指定地址内的脏页面会被写入硬盘。调用失败返回零。

7) 关闭内存映射文件太简单了, CloseHandle搞定

————————

转载:https://www.cnblogs.com/hrhguanli/p/4007100.html

1. Purpose and basic operation: it is used for memory sharing between different processes. It can map a physical file to memory, and then directly use the allocated or open address space of named shared memory to realize resource sharing access

2. Related process 1) create a new named shared memory. First, use CreateFile or createfileformapping to obtain a physical file handle for mapping, and then use the file handle in combination with createfilemapping to obtain a named shared memory mapping file handle.

//CreateFileMapping 为指定文件创建一个有名或无名的文件映象;
HANDLE CreateFileMapping(
  HANDLE hFile,              // 映射文件的句柄
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 安全描写叙述符指针
  DWORD flProtect,           // 对映射对象的保护
  DWORD dwMaximumSizeHigh,   // 对象最大长度的高32位
  DWORD dwMaximumSizeLow,    // 对象最大长度的低32位
  LPCTSTR lpName             // 文件内存映射对象的名字
);

Note: hfile: the handle of the mapping file. The opening mode of the file must be consistent with that specified by the flprotect parameter; Assuming this parameter value is 0xFFFFFFFF, the size of the mapping object must be specified in the dwmaximumsizehigh and dwmaximumsizelow parameters. Moreover, a file mapping object will be created in the operating system virtual memory page replacement file instead of using a disk file. At the same time, the size of the mapping object must be given. File mapping objects are shared by copy, inheritance, or name. Lpfilemappingattributes: security descriptor pointer, which determines whether the return handle can be inherited by the child process. If it is null, the child process cannot inherit. In WinNT, assuming null, the file mapping object gets a default security descriptor. Flprotect: an attempt to specify a protection mode for the resulting file can be set to the following values: page_ Readonly: only the attribute is read, and the corresponding file of hfile must be in generic_ Open in read mode.  PAGE_ Readwrite: readable and writable attribute, and the corresponding file of hfile must be in generic_ Read and generic_ Open as write.  PAGE_ WRITECOPY: the operation after copying the writable area, and the corresponding file of hfile must be in generic_ Read and generic_ Open as write. Dwmaximumsizehigh, dwmaximumsizelow: assuming these two parameters are 0, the maximum length of the file mapping object is equal to the file length specified by hfile. Lpname: the name of the file mapping object. If the name already exists, the mapping object will be processed according to the specified by flprotect. If this parameter is null, a file mapping object without a name is created. Assuming that the name of this parameter is the same as that of the system event, the function fails and GetLastError returns error_ INVALID_ HANDLE;

Return value: if the function call is successful, the handle of the file mapping object is returned. If the file mapping object already exists, the handle of the original mapping object is returned. GetLastError returns error_ ALREADY_ EXISTS。 The function failed to run and returned null.

2) Open named shared memory. Assuming that you need to share an existing named shared memory mapping file, use the openfilemapping function// Openfilemapping opens a named file mapping object

HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // 訪问模式
  BOOL bInheritHandle,    // 继承标志
  LPCTSTR lpName          // 文件映射对象名指针
);

Note: dwdesiredaccess: the access mode is the same as that in mapviewofile. Binherithandle: inheritance flag. Whether it can be inherited and used by a new process. If it is true, it can be inherited and used by a new process. Return value: a named file mapping object is returned successfully, and null is returned for failure.

3) Obtaining the address space pointer for reading and writing memory mapped files is different from general file reading and writing. It is directly facing the address space you apply for. Therefore, you need to use mapviewofile to obtain the pointer of the relevant address LPVOID type. If file writing is required, the memory address can be directly assigned through type conversion, such as memcpy (lpaddress, lpbuf,…) There is a natural need to prevent memory overflow. Suppose it is a read operation, just adjust the parameter order.

MapViewOfFile 在调用进程的地址空间映射一个文件视图
LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,  // 已创建的文件映射对象句柄
  DWORD dwDesiredAccess,      // 訪问模式
  DWORD dwFileOffsetHigh,     // 文件偏移的高32位
  DWORD dwFileOffsetLow,      // 文件偏移的低32位
  DWORD dwNumberOfBytesToMap  // 映射视图的大小
);

Note: hfilemappingobject: the file mapping object handle returned by createfilemapping or openfilemapping. Dwdesiredaccess: the access mode of the mapping view, which is related to the protection mode flprotect for creating file mapping objects. It can be set to the following values: file_ MAP_ Write: a file view with read-write attributes is created, and the protection mode is page_ READWRITE FILE_ MAP_ Read: a file view that only reads attributes is created, and the protection mode is page_ Readwrite or page_ READONLY FILE_ MAP_ ALL_ Access: and file_ MAP_ The write mode is the same as file_ MAP_ Copy: the protection mode is page_ When WRITECOPY, you get a view file. When you write to the view file, the page will exchange itself, and the changes you make will not damage the original data. Dwnumberofbytestomap: maps the size of the file part. If it is 0, the entire file is mapped. Return value: the starting address of the mapping view is returned if successful, and null if failed.

4) Mapviewofileex maps a file view in the address space of the calling process, and agrees that the calling process specifies a special memory address for the mapping view

LPVOID MapViewOfFileEx(
  HANDLE hFileMappingObject,  // 文件映射对象的句柄
  DWORD dwDesiredAccess,      // 訪问模式
  DWORD dwFileOffsetHigh,     // 文件偏移的高32位
  DWORD dwFileOffsetLow,      // 文件偏移的低32位
  DWORD dwNumberOfBytesToMap, // 映射视图的大小
  LPVOID lpBaseAddress        // 指定映射视图的事实上内存地址
);

Note: use the same method as mapviewoffile, but if the specified memory address space is not enough, the function fails.

5) Copy the memory to the mapped physical file. The flushmapviewofffile function can dump the contents in the memory to the physical disk. Flushmviewofffile writes the changed contents or all in the file mapping view back to the disk file

BOOL FlushViewOfFile(
  LPCVOID lpBaseAddress,       // 改动内容的起始地址
  DWORD dwNumberOfBytesToFlush // 改动的字节数目
);

The function runs successfully and returns non-zero.

6) Unload memory mapped file address pointer unmapviewofffile function is to unload unmapviewofffile and delete the mapped view of the file

BOOL UnmapViewOfFile(
  LPCVOID lpBaseAddress   // 映射视图起始地址
);

Note: lpbaseaddress: the starting address of the mapping view, which is generated by the mapviewoffile function mapviewoffileex. Return value: if the call is successful, it returns non-zero, and all dirty pages in the specified address will be written to the hard disk. The call failed and returned zero.

7) It’s too easy to close the memory mapping file. CloseHandle handles it