这两天在复习进程间通信,复习一下记不住,复习一下记不住。。。就写个小博客献个丑,先来第一个内存映射

代码亲测通过

CreateFileMapping()的最后的一位用来做进程间通信

步骤:

1.CreateFileMapping()创建一个内存映射对象
2.利用MapViewOfFile()将文件映射到进程地址空间
3.UnmapViewOfFile()解除映射

Server端

#include "stdafx.h"
#include <windows.h>

int main()
{

HANDLE MappingHandle = NULL;
PVOID BaseAddress = NULL;
MappingHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE/*物理页*/, 0/*高位*/,0x1000/*低位*/, L"HelloWorld");

if (MappingHandle==NULL)
{
return 0;
}

BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);//基地址查找

__try
{
memcpy(BaseAddress, "HelloClient", strlen("HelloClient")+1);

printf("Input AnyKey To Continue\r\n");
getchar();

printf("%s\r\n", BaseAddress);
}
__except (EXCEPTION_EXECUTE_HANDLER)//例外执行
{
printf("异常\r\n");
goto Exit;
}

Exit:
if (MappingHandle!=NULL)
{
CloseHandle(MappingHandle);
MappingHandle = NULL;
UnmapViewOfFile(BaseAddress);

}

printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}

Client端

#include "stdafx.h"
#include <windows.h>

int main()
{

HANDLE MappingHandle = NULL;
PVOID BaseAddress = NULL;
//此下几行代码为主要点
MappingHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"HelloWorld");
if (MappingHandle == NULL)
{
return 0;
}
BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

__try
{
memcpy(BaseAddress, "HelloServer", strlen("HelloWorld") + 1);
printf("%s\r\n", BaseAddress);

}
__except (EXCEPTION_EXECUTE_HANDLER)
{
goto Exit;
}

Exit:

if (MappingHandle != NULL)
{
CloseHandle(MappingHandle);
MappingHandle = NULL;
UnmapViewOfFile(BaseAddress);

}
printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}

函数解释:

CreateFileMapping():

创建或打开指定文件的命名或未命名的文件映射对象。

HANDLE WINAPI CreateFileMapping(
  _In_ HANDLE hFile,
  _In_opt_ LPSECURITY_ATTRIBUTES lpAttributes,
  _In_ DWORD flProtect,
  _In_ DWORD dwMaximumSizeHigh,
  _In_ DWORD dwMaximumSizeLow,
  _In_opt_ LPCTSTR lpName
);

参数
hFile [in]
要从中创建文件映射对象的文件的句柄。
必须使用与flProtect参数指定的保护标志兼容的访问权限打开该文件。它不是必需的,但建议您打开要映射的文件进行独占访问。有关详细信息,请参阅文件安全和访问权限。
如果hFile为INVALID_HANDLE_VALUE,则调用进程还必须在dwMaximumSizeHigh和dwMaximumSizeLow参数中指定文件映射对象的大小。在这种情况下,CreateFileMapping创建一个指定大小的文件映射对象,该对象由系统分页文件而不是文件系统中的文件支持。

lpAttributes [in,optional]
指向SECURITY_ATTRIBUTES结构的指针,用于确定子进程是否可以继承返回的句柄。 SECURITY_ATTRIBUTES结构的lpSecurityDescriptor成员指定新的文件映射对象的安全描述符。

如果lpAttributes为NULL,则不能继承该句柄,并且该文件映射对象将获得默认的安全描述符。文件映射对象的默认安全描述符中的访问控制列表(ACL)来自创建者的主要或模拟令牌。有关更多信息,请参阅文件映射安全和访问权限。

flProtect [in]
指定文件映射对象的页面保护。对象的所有映射视图必须与此保护兼容。

此参数可以是以下值之一。

价值意义
PAGE_EXECUTE_READ
0x20允许将视图映射为只读,写时复制或执行访问。

必须使用GENERIC_READ和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。

Windows Server 2003和Windows XP:在Windows XP SP2和Windows Server 2003 SP1之前,此值不可用。
 
PAGE_EXECUTE_READWRITE
0x40允许将视图映射为只读,写时复制,读/写或执行访问。

必须使用GENERIC_READ,GENERIC_WRITE和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。

Windows Server 2003和Windows XP:在Windows XP SP2和Windows Server 2003 SP1之前,此值不可用。
 
PAGE_EXECUTE_WRITECOPY
0x80允许将视图映射为只读,写时复制或执行访问。该值相当于PAGE_EXECUTE_READ。

必须使用GENERIC_READ和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。

Windows Vista:在Windows Vista SP1之前,此值不可用。

Windows Server 2003和Windows XP:不支持此值。
 
PAGE_READONLY
0x02允许将视图映射为只读或写时拷贝访问。尝试写入特定区域导致访问冲突。
必须使用GENERIC_READ访问权限创建hFile参数指定的文件句柄。
PAGE_READWRITE
0x04允许将视图映射为只读,写时复制或读/写访问。

必须使用GENERIC_READ和GENERIC_WRITE访问权限创建hFile参数指定的文件句柄。
 
PAGE_WRITECOPY
0x08允许将视图映射为只读或写时复制访问。此值相当于PAGE_READONLY。

必须使用GENERIC_READ访问权限创建hFile参数指定的文件句柄。

应用程序可以通过将其与前一页面保护值之一组合来为文件映射对象指定以下属性中的一个或多个。

价值意义
SEC_COMMIT
0x8000000如果文件映射对象由操作系统分页文件(hfile参数为INVALID_HANDLE_VALUE)支持,则指定当文件的视图映射到进程地址空间时,提交整个页面范围而不是保留。系统必须有足够的提交页面来保存整个映射。否则,CreateFileMapping将失败。
SEC_IMAGE
0x1000000指定hFile参数指定的文件是可执行映像文件。

SEC_IMAGE属性必须与页面保护值(如PAGE_READONLY)组合。但是,此页面保护值对可执行映像文件的视图没有影响。通过可执行文件本身确定对可执行映像文件的视图的页面保护。

没有其他属性对SEC_IMAGE有效。
 
SEC_IMAGE_NO_EXECUTE
0x11000000指定hFile参数指定的文件是不执行的可执行映像文件,加载的映像文件将不会运行强制完整性检查。另外,映射使用SEC_IMAGE_NO_EXECUTE属性创建的文件映射对象的视图将不会调用使用PsSetLoadImageNotifyRoutine内核API注册的驱动程序回调。

SEC_IMAGE_NO_EXECUTE属性必须与PAGE_READONLY页面保护值组合。没有其他属性对SEC_IMAGE_NO_EXECUTE有效。

Windows Server 2008 R2,Windows 7,Windows Server 2008,Windows Vista,Windows Server 2003和Windows XP:Windows Server 2012和Windows 8之前不支持此值。
 
SEC_LARGE_PAGES
0x80000000将大页面用于由操作系统页面文件支持的文件映射对象(hfile参数为INVALID_HANDLE_VALUE)。由可执行映像文件或数据文件支持的文件映射对象不支持此属性(hFile参数是可执行映像或数据文件的句柄)。

文件映射对象的最大大小必须是GetLargePageMinimum函数返回的大页面的最小大小的倍数。如果不是,CreateFileMapping将失败。在映射使用SEC_LARGE_PAGES创建的文件映射对象的视图时,基址和视图大小也必须是最小大页面大小的倍数。

SEC_LARGE_PAGES要求在呼叫者令牌中启用SeLockMemoryPrivilege权限。

如果指定SEC_LARGE_PAGES,则也必须指定SEC_COMMIT。

Windows Server 2003:Windows Server 2003 SP1之前,不支持此值。

Windows XP:不支持此值。
 
SEC_NOCACHE
0x10000000将所有页面设置为不可高速缓存。

应用程序不应该使用此属性,除非显式要求设备。使用与SEC_NOCACHE映射的内存的联锁功能可能导致EXCEPTION_ILLEGAL_INSTRUCTION异常。

SEC_NOCACHE要求设置SEC_RESERVE或SEC_COMMIT属性。
 
SEC_RESERVE
0x4000000如果文件映射对象由操作系统页面文件(hfile参数为INVALID_HANDLE_VALUE)支持,则指定当文件的视图映射到进程地址空间时,整个页面范围被保留以供以后使用过程而不是承诺。

可以在后续调用VirtualAlloc函数时提交保留的页面。页面提交后,它们不能被VirtualFree功能释放或分解。

此属性对由可执行映像文件或数据文件支持的文件映射对象(hfile参数是文件的句柄)无效。

SEC_RESERVE不能与SEC_COMMIT组合。
 
SEC_WRITECOMBINE
0x40000000设置要组合的所有页面。

应用程序不应该使用此属性,除非显式要求设备。使用与SEC_WRITECOMBINE映射的内存的联锁功能可能导致EXCEPTION_ILLEGAL_INSTRUCTION异常。

SEC_WRITECOMBINE要求设置SEC_RESERVE或SEC_COMMIT属性。

Windows Server 2003和Windows XP:Windows Vista之前不支持此标志。

dwMaximumSizeHigh [in]
文件映射对象的最大大小的高阶DWORD。

dwMaximumSizeLow [in]
文件映射对象的最大大小的低阶DWORD。

如果此参数和dwMaximumSizeHigh为0(零),则文件映射对象的最大大小等于hFile标识的文件的当前大小。

尝试映射长度为0(零)的文件失败,错误代码为ERROR_FILE_INVALID。应用程序应该测试长度为0(零)的文件,并拒绝这些文件。

lpName [,可选]
文件映射对象的名称。

如果此参数与现有映射对象的名称相匹配,则函数将请求对flProtect指定的保护对象的访问。

如果此参数为NULL,则创建文件映射对象而不使用名称。

如果lpName与现有事件,信号量,互斥量,等待计时器或作业对象的名称相匹配,则该函数将失败,GetLastError函数返回ERROR_INVALID_HANDLE。这是因为这些对象共享同一个命名空间。

该名称可以具有“全局”或“本地”前缀,以在全局或会话命名空间中显式创建对象。名称的其余部分可以包含除反斜杠字符(\)之外的任何字符

MapViewOfFile():

将文件映射的视图映射到调用进程的地址空间。
要为视图指定建议的基址,请使用MapViewOfFileEx函数。但是,不推荐这种做法。
LPVOID WINAPI MapViewOfFile(
  _In_ HANDLE hFileMappingObject,
  _In_ DWORD dwDesiredAccess,
  _In_ DWORD dwFileOffsetHigh,
  _In_ DWORD dwFileOffsetLow,
  _In_ SIZE_T dwNumberOfBytesToMap
);
Return value
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
参数
hFileMappingObject [in]
文件映射对象的句柄。 CreateFileMapping和OpenFileMapping函数返回此句柄。
dwDesiredAccess [in]
访问文件映射对象的类型,确定页面的保护。此参数可以是以下值之一。
价值意义
FILE_MAP_ALL_ACCESS映射文件的读/写视图。文件映射对象必须使用PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当与MapViewOfFile函数一起使用时,FILE_MAP_ALL_ACCESS等同于FILE_MAP_WRITE。
 
FILE_MAP_COPY映射文件的写时复制视图。文件映射对象必须使用PAGE_READONLY,PAGE_READ_EXECUTE,PAGE_WRITECOPY,PAGE_EXECUTE_WRITECOPY,PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当进程写入写时复制页面时,系统将原始页面复制到进程私有的新页面。新页面由页面文件支持。新页面的保护从写时复制变为读/写。

当指定写时复制访问时,系统和进程提交的费用用于整个视图,因为调用进程可以潜在地写入视图中的每个页面,使所有页面都是私有的。新页面的内容永远不会写回原始文件,并且在视图未映射时丢失。
 
FILE_MAP_READ映射文件的只读视图。尝试写入文件视图会导致访问冲突。

必须使用PAGE_READONLY,PAGE_READWRITE,PAGE_EXECUTE_READ或PAGE_EXECUTE_READWRITE保护创建文件映射对象。
 
FILE_MAP_WRITE映射文件的读/写视图。文件映射对象必须使用PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当与MapViewOfFile一起使用时,(FILE_MAP_WRITE | FILE_MAP_READ)和FILE_MAP_ALL_ACCESS等效于FILE_MAP_WRITE。

上述值中的每一个可以与以下值组合。
价值意义
FILE_MAP_EXECUTE映射文件的可执行视图(映射内存可以作为代码运行)。文件映射对象必须使用PAGE_EXECUTE_READ,PAGE_EXECUTE_WRITECOPY或PAGE_EXECUTE_READWRITE保护创建。
Windows Server 2003和Windows XP:此值可从Windows XP SP2和Windows Server 2003 SP1启动。
对于使用SEC_IMAGE属性创建的文件映射对象,dwDesiredAccess参数不起作用,应设置为任何有效值,如FILE_MAP_READ。
dwFileOffsetHigh [in]
视图开始的文件偏移量的高阶DWORD。

dwFileOffsetLow [in]
视图要开始的文件偏移量的低阶DWORD。高和低偏移量的组合必须在文件映射内指定偏移量。它们还必须匹配系统的内存分配粒度。也就是说,偏移量必须是分配粒度的倍数。要获取系统的内存分配粒度,请使用GetSystemInfo函数,该函数填充SYSTEM_INFO结构的成员。

dwNumberOfBytesToMap [in]
要映射到视图的文件映射的字节数。所有字节必须在CreateFileMapping指定的最大大小之内。如果此参数为0(零),映射将从指定的偏移扩展到文件映射的结尾。

进程间通信之利用CreateFilemapping()的更多相关文章

  1. [转]Windows环境下利用“共享内存”实现进程间通信的C/C++代码---利用CreateFileMapping和MapViewOfFile

    http://blog.csdn.net/stpeace/article/details/39534361 进程间的通信方式有很多种, 上次我们说了最傻瓜的“共享外存/文件”的方法. 那么, 在本文中 ...

  2. node进程间通信

    作为一名合格的程序猿/媛,对于进程.线程还是有必要了解一点的,本文将从下面几个方向进行梳理,尽量做到知其然并知其所以然: 进程和线程的概念和关系 进程演进 进程间通信 理解底层基础,助力上层应用 进程 ...

  3. Android程序员必须掌握的知识点-多进程和多线程

    当某个应用组件启动且该应用没有运行其他任何组件时,Android 系统会使用单个执行线程为应用启动新的 Linux 进程.默认情况下,同一应用的所有组件在相同的进程和线程(称为"主" ...

  4. Linux 初识Libevent网络库

    初识Libevent libevent是用c写的高并发网络io库,只要有文件描述符,就都可使用libevent. libevent使用回调函数(callback) . 有了libevent,网络编程我 ...

  5. 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发

    子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...

  6. Python 进程、线程、协程的介绍与使用

    一.必备的理论基础 二.操作系统发展史 三.进程理论 四.线程理论 五.协程 一.必备的理论基础 操作系统理论: 操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的控制程序 操作系统的两大功 ...

  7. Python中的多进程、多线程和协程

    本文中的内容来自我的笔记.撰写过程中参考了胡俊峰老师<Python程序设计与数据科学导论>课程的内容. 并发处理:多进程和多线程 前置 概念: 并发:一段时间内同时推进多个任务,但不一定要 ...

  8. 【Android】17.5 利用Messenger实现进程间通信(IPC)

    分类:C#.Android.VS2015: 创建日期:2016-03-03 一.Messager类简介 本章前面曾经说过,要在Android上执行带服务的进程间通信(IPC),既可以用Messenge ...

  9. 进程间通信 - 动态链接库中共享内存(利用DLL的2~3G的地址段空间)

    前言 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据,以及其他的一些资源组成.32位系统的进程分配4G的虚拟地址空间.内存地址范围是0x00000000-0xFFFFFF ...

随机推荐

  1. java基础,集合,HashMap,源码解析

    最怕,你以为你懂咯,其实你还不懂: 见贤思齐,看看那些我们习以为常的集合,通过相关定义.源码,思考分析,加深对其的理解,提高编码能力,能做一个略懂的程序员: 做几个我们常用的集合类.开篇HashMap ...

  2. [Spark性能调优] 第四章 : Spark Shuffle 中 JVM 内存使用及配置内幕详情

    本课主题 JVM 內存使用架构剖析 Spark 1.6.x 和 Spark 2.x 的 JVM 剖析 Spark 1.6.x 以前 on Yarn 计算内存使用案例 Spark Unified Mem ...

  3. 微信小程序 - 上拉加载

    demo.wxml  文件 <view wx:for="{{listdata}}" wx:key="listdata" class='listitem'& ...

  4. 卸载CentOS7-x64自带的OpenJDK并安装Sun的JDK7的方法

    第一步:查看并卸载CentOS自带的OpenJDK 安装好的CentOS会自带OpenJdk,用命令 java -version ,会有下面的信息: java version "1.6.0& ...

  5. 8、ABPZero系列教程之拼多多卖家工具 添加手机注册登录功能

    现在网站基本都用手机注册,很少用邮箱注册,本篇内容比较多,代码我会尽量加备注,有些操作需要连续添加几个文件才不报错,如果VS显示错误,请继续后续步骤. 前面已经有一篇文章讲到集成短信发送模块:http ...

  6. 关于CSS的table-layout属性的用法详解

    前言: 今天来和大家详细说一下table-layout属性的用法. /*eg:设置表格布局算法*/ table{ table-layout:fixed; } ***本文关键词:table-layout ...

  7. 【转载】IdentityServer4 使用OpenID Connect添加用户身份验证

    使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...

  8. Nginx是如何处理Request的?

    nginx是如何匹配过来的请求,然后做处理的呢?这个匹配的过程可以分为两步: 1.选择server 2.选择location    选择server 仅仅匹配server name 加入Nginx的配 ...

  9. TLD算法原理--学习理解之(二)

    正如名字所示,TLD算法主要由三个模块构成:追踪器(tracker),检测器(detector)和机器学习(learning). 对于视频追踪来说,常用的方法有两种,一是使用追踪器根据物体在上一帧的位 ...

  10. Echarts---柱状图实现

    做Echarts很简单,可以参看官网 http://echarts.baidu.com/index.html 作为程序员我们只需要把静态数据替换成我们自己需要的! 下面看一个自己做的例子: 还是先看看 ...