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

本文实现了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. 搭建redis集群时所遇问题及解决方法

    单独一台虚拟机(系统CentOS 7) 问题1 创建redis集群环境时,输入以下命令 [root@localhost redis-cluster]# ./redis-trib.rb create - ...

  2. JNA 相关问题

    JNA 相关问题 结构体对齐问题 要注意调用的c库字段对齐方式的相关设置. #pragma pack (push,1) #pragma pack(pop) jna中提供了4种对齐方式: /** Use ...

  3. Java方法中传值和引用传递的问题(转)

    说明:标题其实说法是错误的.Java中只有值传递,没有引用传递. ... ... //定义了一个改变参数值的函数 public static void changeValue(int x) { x = ...

  4. Microsoft SQL Server 2005技术内幕:存储引擎笔记

    http://www.cnblogs.com/lyhabc/articles/3942053.html

  5. 在asp.net 项目的bin目录中使用子目录

    如果要动态发布第三方扩展或者对asp.net项目进行二次开发时,希望不影响原有的程序并保持原有bin完整性,可以将扩展放到bin下的子目录中,并修改web.config的相应配置. 原配置: < ...

  6. 讯飞语音识别Android-Demo

    import java.io.UnsupportedEncodingException; import android.app.Activity; import android.os.Bundle; ...

  7. Hibernate注解详解

    一.实体Bean 每个持久化POJO类都是一个实体Bean, 通过在类的定义中使用 @Entity 注解来进行声明. 声明实体Bean @Entitypublic class Flightimplem ...

  8. GO语言_用redis作为url队列的爬虫

    // Copyright 2016 laosj Author @songtianyi. All Rights Reserved. // // Licensed under the Apache Lic ...

  9. mac 当前位置打开终端

    做开发时经常会遇到在当前目录打开终端的情况,一直都是先启动终端,然后再切换到当前目录,今天发现了一个新的方法,虽然不是一步到位,但比以前快多了.   工具/原料   mac系统 苹果电脑 方法/步骤 ...

  10. Cucumber+Rest Assured快速搭建api自动化测试平台

    转载:http://www.jianshu.com/p/6249f9a9e9c4 什么是Cucumber?什么是BDD?这里不细讲,不懂的直接查看官方:https://cucumber.io/ 什么是 ...