【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

 

进程间通信的方式有很多种,其底层原理使用的都是内存映射文件。

本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信。

 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子_第1张图片

进程1

按钮【Create  mapping of Data】用来创建命名内存映射文件,后备存储器为页交换文件,而非磁盘上的文件,大小为4K,将全部大小映射到进程地址空间,将Data中的数据写入该内存映射文件,然后撤销对文件视图的映射。注意在进程1里不能CloseHandle(m_hFileMapping)

 

进程2

按钮【Open maping and get Data】用来打开进程1创建的命名内存映射文件,将全部大小映射到进程地址空间,从中读出数据,将数据内容放到Data里。 

按钮【Close mapping of Data】用来关闭CloseHandle进程1返回的内存映射文件m_hFileMapping。

 1 void CMemoryMappingDlg::OnBnClickedBtnCreate2()  2 {  3     // TODO: 在此添加控件通知处理程序代码;
 4     LPCTSTR lpFileMappingName = _T("MMFSharedData");  5     m_hFileMapping = CreateFileMapping(  6         INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4 * 1024, lpFileMappingName);  7     DWORD dwErr = GetLastError();  8 
 9     if (NULL == m_hFileMapping ) 10  { 11         AfxMessageBox(_T("无法创建该内存映射文件")); 12         return; 13  } 14     if (dwErr == ERROR_ALREADY_EXISTS) 15  { 16         AfxMessageBox(_T("存在同名内存映射文件")); 17  CloseHandle(m_hFileMapping); 18         return; 19  } 20 
21     PVOID pMapOfView = MapViewOfFile(m_hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 /*4 * 1024*/); 22     if (NULL == pMapOfView) 23  { 24         AfxMessageBox(_T("映射该文件错误")); 25  CloseHandle(m_hFileMapping); 26         return; 27  } 28 
29     ZeroMemory(pMapOfView, 4 * 1024); 30 
31  CString strText; 32  GetDlgItemText(IDC_EDIT_DATA, strText); 33     memcpy_s(pMapOfView, (strText.GetLength() + 1) * sizeof(TCHAR), strText.GetBuffer(), 34         (strText.GetLength() + 1) * sizeof(TCHAR)); 35 
36  UnmapViewOfFile(pMapOfView); 37     //CloseHandle(m_hFileMapping); 不能执行此句,否则进程2不能打开该命名内存映射文件。
38 } 39 
40 void CMemoryMappingDlg::OnBnClickedBtnClose() 41 { 42     // TODO: 在此添加控件通知处理程序代码;
43  CloseHandle(m_hFileMapping); 44 } 45 
46 void CMemoryMappingDlg::OnBnClickedBtnOpen() 47 { 48     // TODO: 在此添加控件通知处理程序代码
49     LPCTSTR lpFileMappingName = _T("MMFSharedData"); 50 
51     //OpenFileMapping的第一个参数一定不能是PAGE_**, 区别于CreateFileMapping函数 52     //HANDLE hFileMapping = OpenFileMapping(PAGE_READWRITE, FALSE, lpFileMappingName);
53     HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileMappingName); 54 
55     if (NULL == hFileMapping) 56  { 57         AfxMessageBox(_T("打不开该内存映射文件")); 58         return; 59  } 60 
61     PVOID pMapOfFile = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 /*4 * 1024 */); 62     if (NULL == pMapOfFile) 63  { 64         AfxMessageBox(_T("映射该文件错误")); 65  CloseHandle(hFileMapping); 66         return; 67  } 68 
69     TCHAR tchArr[256]; 70     ZeroMemory(tchArr, sizeof(tchArr)); 71     memcpy_s(tchArr, sizeof(tchArr), pMapOfFile, sizeof(tchArr)); 72  SetDlgItemText(IDC_EDIT_DATA, tchArr); 73 
74  UnmapViewOfFile(pMapOfFile); 75  CloseHandle(hFileMapping); 76 }

 

 

 需要注意的地方是:

0、后备存储器为页交换文件的内存映射文件,CreateFileMapping的文件句柄参数为INVALID_HANDLE_VALUE

1、进程1创建了命名内存映射文件后,一定不能CloseHandle(内存映射文件句柄),否则进程2不能OpenFileMapping打开该命名内存映射文件

2、OpenFileMapping的第一个参数一定不能是PAGE_**, 区别于CreateFileMapping函数

 

 

 

 

 

你可能感兴趣的:(【Windows核心编程】一个使用内存映射文件进行进程间通信的例子)