共享内存就是说白了就是一种映射。我参考了XOR以及网易“开心一族的博客”的东西。在(winXP+vs2008环境下编译通过)
共享内存在 Windows 中是用 FileMapping 实现的。
HANDLE CreateFileMapping( //返回File Mapping Object的句柄 HANDLE hFile, // 想要产生映射的文件的句柄 LPSECURITY_ATTRIBUTES lpAttributes, // 安全属性(只对NT和2000生效) DWORD flProtect, // 保护标致 DWORD dwMaximumSizeHigh, // 在DWORD的高位中存放 File Mapping Object // 的大小 DWORD dwMaximumSizeLow, // 在DWORD的低位中存放 File Mapping Object // 的大小(通常这两个参数有一个为0) LPCTSTR lpName // File Mapping Object的名称。 );
我们可以用 CreateFileMapping 创建一个内存文件映射对象, CreateFileMapping 这个 API 将创建一个内核对象,用于映射文件到内存。这里,我们并不需要一个实际的文件,所以,就不需要调用 CreateFile 创建一个文件, hFile 这个参数可以填写 INVALID_HANDLE_VALUE 。但是,文件长度是需要填的。Windows 支持长达 64bit 的文件,但是这里,我们的需求一定不会超过 4G , dwMaximumSizeHigh 一定是 0 ,长度填在 dwMaximumSizeLow 即可。然后调用 MapViewOfFile 映射到当前进程的虚拟地址上即可。一旦用完共享内存,再调用 UnmapViewOfFile 回收内存地址空间。
以下有2个进程,A.c生成A进程,B.c生成b进程。那么A进程将不停地写入名为"Global\\MyFileMappingObject"的共享内存块,而B进程不停地读名为"Global\\MyFileMappingObject"的共享内存块。从而实现IPC
a.c
#include <stdio.h> #include <windows.h> #define BUF_SIZE 1024 char szName[]="Global\\MyFileMappingObject"; //指向同一块共享内存的名字 int main() { HANDLE hMapFile; LPCTSTR pBuf; hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security PAGE_READWRITE, // read/write access 0, // maximum object size (high-order DWORD) BUF_SIZE, // maximum object size (low-order DWORD) szName); // name of mapping object if (hMapFile == NULL) { printf("Could not create file mapping object (%d).\n"); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { printf("Could not map view of file (%d).\n"); CloseHandle(hMapFile); return 1; } //从main开始至此,A B process代码一样,都是获取名为"Global\\MyFileMappingObject"的共享内存的指针 //以下代码,A不停写共享内存pBuf while(1) { char source[BUF_SIZE]; scanf("%s",source); printf("B process: %s to be transfered to A process.\n", source); memcpy((PVOID)pBuf, source, BUF_SIZE); } }
//b.c #include <windows.h> #include <stdio.h> #define BUF_SIZE 1024 char szName[]="Global\\MyFileMappingObject"; //指向同一块共享内存的名字 int main(int argc, char *argv[]) { HANDLE hMapFile; LPCTSTR pBuf; hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, //物理文件句柄 NULL, // default security PAGE_READWRITE, // read/write access 0, //高位文件大小 BUF_SIZE, //低位文件大小 szName); //共享内存名称 if (hMapFile == NULL) { printf("Could not create file mapping object (%d).\n"); return 1; } //拷贝数据到共享文件里 pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { printf("Could not map view of file (%d).\n"); CloseHandle(hMapFile); return 1; } /B不停地读共享内存pBuf while(1) { printf(pBuf); printf(" is here 0x%x", &pBuf); getchar(); } UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; }