【Windows核心编程】一个使用内存映射文件进行进程间通信的例子
进程间通信的方式有很多种,其底层原理使用的都是内存映射文件。
本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信。
进程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函数
**********************技术交流请 email:cuihao0532#163.com 欢迎转载,转载请注明出处!***************************** 如果对本文满意请扫描文章左侧【二维码添加微信】获取更多好玩、有趣、有益、有营养的料,
你我共同成长!Y(^_^)Y
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗