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

本文实现了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。

 void CMemoryMappingDlg::OnBnClickedBtnCreate2()
{
// TODO: 在此添加控件通知处理程序代码;
LPCTSTR lpFileMappingName = _T("MMFSharedData");
m_hFileMapping = CreateFileMapping(
INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, , * , lpFileMappingName);
DWORD dwErr = GetLastError(); if (NULL == m_hFileMapping )
{
AfxMessageBox(_T("无法创建该内存映射文件"));
return;
}
if (dwErr == ERROR_ALREADY_EXISTS)
{
AfxMessageBox(_T("存在同名内存映射文件"));
CloseHandle(m_hFileMapping);
return;
} PVOID pMapOfView = MapViewOfFile(m_hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, , , /*4 * 1024*/);
if (NULL == pMapOfView)
{
AfxMessageBox(_T("映射该文件错误"));
CloseHandle(m_hFileMapping);
return;
} ZeroMemory(pMapOfView, * ); CString strText;
GetDlgItemText(IDC_EDIT_DATA, strText);
memcpy_s(pMapOfView, (strText.GetLength() + ) * sizeof(TCHAR), strText.GetBuffer(),
(strText.GetLength() + ) * sizeof(TCHAR)); UnmapViewOfFile(pMapOfView);
//CloseHandle(m_hFileMapping); 不能执行此句,否则进程2不能打开该命名内存映射文件。
} void CMemoryMappingDlg::OnBnClickedBtnClose()
{
// TODO: 在此添加控件通知处理程序代码;
CloseHandle(m_hFileMapping);
} void CMemoryMappingDlg::OnBnClickedBtnOpen()
{
// TODO: 在此添加控件通知处理程序代码
LPCTSTR lpFileMappingName = _T("MMFSharedData"); //OpenFileMapping的第一个参数一定不能是PAGE_**, 区别于CreateFileMapping函数
//HANDLE hFileMapping = OpenFileMapping(PAGE_READWRITE, FALSE, lpFileMappingName);
HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileMappingName); if (NULL == hFileMapping)
{
AfxMessageBox(_T("打不开该内存映射文件"));
return;
} PVOID pMapOfFile = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, , , /*4 * 1024 */);
if (NULL == pMapOfFile)
{
AfxMessageBox(_T("映射该文件错误"));
CloseHandle(hFileMapping);
return;
} TCHAR tchArr[];
ZeroMemory(tchArr, sizeof(tchArr));
memcpy_s(tchArr, sizeof(tchArr), pMapOfFile, sizeof(tchArr));
SetDlgItemText(IDC_EDIT_DATA, tchArr); UnmapViewOfFile(pMapOfFile);
CloseHandle(hFileMapping);
}

需要注意的地方是:

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

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

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

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

  1. Java编程思想:内存映射文件

    import java.io.*; import java.nio.IntBuffer; import java.nio.MappedByteBuffer; import java.nio.chann ...

  2. 《windows核心编程系列》十八谈谈windows钩子

    windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...

  3. 《windows核心编程系列》十六谈谈内存映射文件

    内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...

  4. Windows核心编程 第十七章 -内存映射文件(下)

    17.3 使用内存映射文件 若要使用内存映射文件,必须执行下列操作步骤: 1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件. 2) 创建一个文件映射内核对象,告诉系统该 ...

  5. Windows核心编程 第十七章 -内存映射文件(上)

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

  6. 《windows核心编程》 17章 内存映射文件

    内存映射文件主要用于以下三种情况: 系统使用内存映射文件载入并运行exe和dll,这大量节省了页交换文件的空间以及应用程序的启动时间 开发人员可以使用内存映射文件来访问磁盘上的数据文件.这使得我们可以 ...

  7. Java编程的逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  8. 文件映射(Windows核心编程)

    映射内存的可执行文件和dll 当一个线程调用CreateProcess的时候,系统会执行以下步骤: 系统会先确定CreateProcess所指定的可执行文件的所在位置.如果找不到文件,那么Create ...

  9. 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件

    本文背景: 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用:根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制. 本 ...

随机推荐

  1. Ruby自动化测试(操作符的坑)

    事情是这样的: times++ @ddr = DDR::DDR.new() 执行到这里的时候,总是报错:'+@' undefied method.刚开始的时候以为是机器在重启过程中一些不稳定函数调用或 ...

  2. AC日记——丢瓶盖 洛谷 P1316

    题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...

  3. 获取某个元素相对于视窗的位置-getBoundingClientRect

    1. getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 语法:这个方法没有参数 rectObject = ...

  4. C# 生成二维码(带Logo)

    C# 生成二维码(带Logo) 第一种方式 我们需要引用 ThoughtWorks.QRCode.dll  生成带logo二维码(framework4.0以上) 下载地址:https://pan.ba ...

  5. java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.github.pagehelper.Page pagehelper报错无法类型转化。

    报错信息: 严重: Servlet.service() for servlet [springmvc] in context with path [] threw exception [Request ...

  6. 邁向IT專家成功之路的三十則鐵律 鐵律二十一:IT人用才之道-穿透

    在以道德為基礎的企業主管之人,其最根本的能力除了須要有洞悉事物的敏捷思維之外,眼光還必要有像水柱般一樣的穿山引石之能,如此不僅能夠為企業找到適才之人,更能為企業的永續經營奠定有如泰山般的基石.只可惜大 ...

  7. Eclipse 教程

    Eclipse 教程 Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成 ...

  8. BIEE11G系统数据源账号过期问题(默认安装步骤)

    BIEE默认完毕安装后处于安全的考虑会对BI系统账户设定180天的有效期设置.例如以下图所看到的: 当账户超过时间后会自己主动口令失效.而造成BI系统启动失败.无法正常訪问等相关问题,到时候又一次设置 ...

  9. 关于在 C#中无法静态库引用的解决方法

    在VS中用C#写了个类库,后面想转成静态库发现没有直接的方法,原来在C++中可以,而C#中不支持. 但是有时候程序引用C#编写的动态库觉得用户体验不好太累赘,想要简单只发一个exe可执行程序给用户就好 ...

  10. POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]

    SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11384   Accepted: 3572 Case T ...