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

 

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

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

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

进程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。

【Windows核心编程】一个使用内存映射文件进行进程间通信的例子
 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 }
【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

 

 

 需要注意的地方是:

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

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

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

 

 

 

 

 

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

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

上一篇:打码util


下一篇:Jenkins Publish over SSH Exec command 不打印输出