内存映像文件可以映射一个文件、一个文件中的指定区域或者指定的内存块,其中的数据就可以用内存读取指令来直接访问,而不用频繁的使用操作文件的I/O系统函数,从而提高文件的存取速度和效率。
映像文件的另一个重要作用就是用来支持永久命名的共享内存。要在两个应用程序之间共享内存,可以在一个应用程序中创建一个文件并映射,然后另外一个程序通过打开和映射此文件,并把它当作自己进程的内存来使用。事实上,此内存是所有进程共享的。
下面将先描述一下几个操作内存的API函数
1、创建内存映射的API函数
This function creates a named or unnamed file-mapping object for the specified file.
HANDLE CreateFileMapping(
//通过调用fileopen or FileCreate后返回的文件句柄,如果是内存,则//$FFFFFFFF
HANDLE hFile,
//安全性结构,一般null
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
//文件试图的保护类型,PAGE_READONLY,PAGE_READWRITE,
DWORD flProtect,
//文件大小的高32位,一般设置为0,除非文件大于4G
DWORD dwMaximumSizeHigh,
//文件大小低32位
DWORD dwMaximumSizeLow,
//映射的名字
LPCTSTR lpName
);
2、打开一个映射文件
HANDLE OpenFileMapping(
//访问数据模式:FILE_MAP_ALL_ACCESS,FILE_MAP_COPY,FILE_MAP_READ, //FILE_MAP_WRITE
DWORD dwDesiredAccess,
//子进程是否可以继承
BOOL bInheritHandle,
//映射文件名
LPCTSTR lpName
);
3、将映射文件映射到本进程的API函数
LPVOID MapViewOfFile(
//通过CreateFileMapping或OpenFileMapping返回的文件句柄
HANDLE hFileMappingObject,
//访问的数据模式:FILE_MAP_WRITE,FILE_MAP_READ,FILE_MAP_ALL_ACCESS
DWORD dwDesiredAccess,
//指定数据在映射文件中起始位置的高32位
DWORD dwFileOffsetHigh,
//低32位
DWORD dwFileOffsetLow,
//需要映射的大小,0表示全部
DWORD dwNumberOfBytesToMap
);
4、关闭映射的api函数
BOOL UnmapViewOfFile(
//由MapViewofFile产生的映射文件的地址
LPCVOID lpBaseAddress
);
5、下面例子中还会用到的几个api函数
创建互斥对象
HANDLE WINAPI CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
上文中曾经提到我们使用内存映射的方式来在多个程序或DLL中共享数据。下面就通过一个程序来介绍。
虽然我要描述的是再两个应用程序之间共享数据,不过为了省事,我将所有的内容都写在一个程序中,你只需要把此程序打开两次就可以了。一个程序用来建立内存映射文件,另外一个程序用来打开内存映射文件。并通过对公共内存的读写操作来演示信息共享。
代码已经打包下载
迅雷专用高速下载