C++ Windows进程间共享内存通信

这篇具有很好参考价值的文章主要介绍了C++ Windows进程间共享内存通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

在项目工程中需要64位程序调用32位程序并加以通信。 实现了两个进程间的内存共享。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Windows 进程间共享内存通信

1、进程间通信原理:

C++ Windows进程间共享内存通信

主要实现:
• 系统使用内存映射文件,以便加载和执行. exe和DLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。
• 可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作,并且可以不必对文件内容进行缓存。
• 可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据。Windows确实提供了其他一些方法,以便在进程之间进行数据通信,但是这些方法都是使用内存映射文件来实现的,这使得内存映射文件成为单个计算机上的多个进程互相进行通信的最有效的方法。

2、使用到的API

typedef struct _SYSTEM_INFO {
  union {
    DWORD dwOemId; //为了兼容而保留的已过时成员。
    struct {
      WORD wProcessorArchitecture;
      WORD wReserved;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
  DWORD     dwPageSize;  //页面大小和页面保护和承诺的粒度。这是VirtualAlloc函数使用的页面大小
  LPVOID    lpMinimumApplicationAddress;//指向应用程序和动态链接库可访问的·最低·内存地址的指针,(DLL)
  LPVOID    lpMaximumApplicationAddress; //指向应用程序和DLL可访问的·最高·内存地址的指学针
  DWORD_PTR dwActiveProcessorMask; //一个掩码,表示配置未系统中的处理器集。位0时处理器0;位31时处理器31
  DWORD     dwNumberOfProcessors; //当前组中的逻辑处理器数。
  DWORD     dwProcessorType; //处理器类型
  DWORD     dwAllocationGranularity;  //可在其中分配虚拟内存的起始地址的粒度。
  WORD      wProcessorLevel; //依赖于体系结构的处理器级别。它应仅用于显示目的。
  WORD      wProcessorRevision;//依赖于体系结构的处理器修订版本。
} SYSTEM_INFO, *LPSYSTEM_INFO; //系统用信息

SYSTEM_INFO结构 ——sysinfoapi.h

1、GetSystemInfo

参数 功能
[out] LPSYSTEM_INFO lpSystemInfo 指向接受信息的SYSTEM_INFOj结构的指针

2、HANDLE CreateFileMapping( HANDLE hFile,LPSECURITY_ATTRIBUTES lpAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName ); —创建共享内存

参数 功能
HANDLE 物理文件句柄,返回值
HANDLE hFile 物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes 安全设置(一般位NULL)
DWORD dwMaximumSizeHigh 高位文件大小
DWORD dwMaximumSizeLow 低位文件大小
LPCTSTR lpName 共享内存名称

3、HANDLE OpenFileMapping(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName ); --打开一个又名的共享内存

参数 功能
HANDLE [返回值]成功打开lpName名字的共享内存地址;失败,返回NULL
DWORD dwDesiredAccess 通道模式
BOOL bInheritHandle 继承标志位
LPCTSTR lpName 文件映射目标的名称指针

4、LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap); --映射共享内存地址空间

参数 介绍
LPVOID [返回]成功:映射的地址;失败:NULL
HANDLE hFileMappingObject 文件映射目标到映射到地址空间
DWORD dwDesiredAccess 存取模式
DWORD dwFileOffsetHigh 高阶 32 位文件偏移量
DWORD dwFileOffsetLow 低阶32位文件偏移量
DWORD dwNumberOfBytesToMap 映射字节位数

5、BOOL UnmapViewOfFile( LPCVOID lpBaseAddress ); --解除映射

参数 介绍
BOOL [返回] 成功:非0; 失败:0;
LPCVOID lpBaseAddress 映射地址起始位置, MapViewOfFile 的句柄

6、BOOL CloseHandle(HANDLE hObject) --关闭打开的句柄

参数 介绍
BOOL [返回]成功:true;失败:false;
HANDLE hObject 要关闭的目标句柄

二、信号量:
在另个进程访问共享内存时,会造成数据访问冲突。需要使用信号量来限制该访问顺序。

1、CreateSemaphore 创建信号量对象

HANDLE WINAPI CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,
LONG lMaximumCount,LPCTSTR lpName);

参数 介绍
HANDLE [返回]成功:返回信号量句柄;失败:NULL;
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, 设置安全属性
LONG lInitialCount 初始的计数值
LONG lMaximumCount 最大的计数值
LPCTSTR lpName 对信号量对象命名

2、OpenSemaphore 通过信号量名,获得信号量对象句柄

HANDLE WINAPI OpenSemaphore(DWORD dwDesireAccess,BOOL bInheritHandle,LPCTSTR lpName);

参数 介绍
HANDLE [返回]成功:返回信号量句柄;失败:NULL;
DWORD dwDesireAccess -SEMAPHORE_ALL_ACCESS-
BOOL bInheritHandle 是否继承
LPCTSTR lpName 信号量名称

3、ReleaseSemaphore释放信号量

BOOL WINAPI ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount);

参数 介绍
BOOL [返回]成功:true;失败:false;
HANDLE hSemaphore 信号量句柄
LONG lReleaseCount 可以释放多个计数
LPLONG lpPreviousCount 上一个计数

4、WaitForSingleObject 等待指定对象处于信号状态或超时间隔已过

DWORD WaitForSingleObject( [in] HANDLE hHandle, [in] DWORD dwMilliseconds)

参数 介绍
DWORD [返回]成功,则返回值指示导致函数返回的事件。失败:返回错误代码
[in] HANDLE hHandle 对象的句柄
[in] DWORD dwMilliseconds 超时间隔(以毫秒为单位)

函数检查指定对象的当前状态。 如果对象的状态未对齐,则调用线程将进入等待状态,直到发出该对象信号或超时间隔。
该函数修改某些类型的同步对象的状态。 修改仅适用于指示状态导致函数返回的对象。 例如,信号灯对象的计数减少一个。


三、从内存中取值

1、CopyMemory 拷贝内存数据

void CopyMemory( In PVOID Destination, In const VOID *Source, In SIZE_T Length);

参数 介绍
void [返回]成功:true;失败:false;
Destination A pointer to the starting address of the copied block’s destination.
Source A pointer to the starting address of the block of memory to copy.
Length The size of the block of memory to copy, in bytes.

如果源块和目标块重叠,则结果未定义。对于重叠块,请使用MoveMemory函数。

2、MoveMemory 拷贝内存数据

void MoveMemory( In PVOID Destination, In const VOID *Source, In SIZE_T Length);

参数 介绍
void [返回]成功:true;失败:false;
Destination A pointer to the starting address of the move destination.
Source A pointer to the starting address of the block of memory to be moved.
Length The size of the block of memory to move, in bytes.

This function is defined as the RtlMoveMemory function. Its implementation is provided inline. The source and destination blocks may overlap.

二、 案例:

C++ Windows进程间共享内存通信

结论:操纵同一块内存地址。

Server服务器:

void SharedMemory()
{
	HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
		NULL,
		PAGE_READWRITE,
		0,
		256,
		TEXT("MySharedMemory")
		);
	LPBYTE pcMap = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 
									0, 0, 0);
 
	char *pSharedStr = "0this is my shared memory";
	memcpy(pcMap, pSharedStr, strlen(pSharedStr));
 
	while (pcMap[0] == '0')	
	{
		Sleep(100);
	}
 
	// 释放内存
	UnmapViewOfFile(pcMap);
	CloseHandle(hFileMapping);
}

Client 客户端

void TestSharedMemory()
{
	HANDLE hFileMapping;
	LPBYTE pcMap;
 
	hFileMapping = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, TEXT("MySharedMemory"));  
	if(hFileMapping == NULL)
	{
		return;
	}
 
	pcMap = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS,
		0, 0, 0);
 
 
	cout << pcMap << endl;
 
	// 通知主程序释放
	pcMap[0] = '1';
 
 
	// 释放内存
	UnmapViewOfFile(pcMap);
	CloseHandle(hFileMapping);
}

总结

这次先写到这里,例子下次再写。文章来源地址https://www.toymoban.com/news/detail-438848.html

到了这里,关于C++ Windows进程间共享内存通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux——进程通信之共享内存

    目录 一.  回顾上文 二.共享内存 1.定义 2.特点: 3.实现步骤: 如下为成功链接共享内存使用权的完整步骤: 4.函数介绍         4.1shmget函数         4.1.2参数介绍                4.2ftok函数:         4.2.1参数介绍                 关于ftok(); shmget();函数的

    2024年02月12日
    浏览(53)
  • (26)Linux 进程通信之共享内存(共享储存空间)

    共享内存是System V版本的最后一个进程间通信方式。 共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内

    2024年01月16日
    浏览(46)
  • 【Linux】进程间通信——管道/共享内存

    进程间通信( Inter-Process Communication,简称IPC )是指不同进程之间进行数据交换和共享信息的机制和技术。在操作系统中,每个进程都是独立运行的,有自己的地址空间和数据,因此进程之间需要一种机制来进行通信,以便彼此协调工作、共享数据或者进行同步操作。 进程间

    2024年02月16日
    浏览(44)
  • 进程间通信--共享内存详解【Linux】

    本文详细讲解了共享内存的原理和使用,并且通过实例代码角度来深度理解共享内存,下面就让我们开始吧。 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源。 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(

    2024年02月02日
    浏览(42)
  • Linux 共享内存mmap,进程通信

    进程间通信是操作系统中重要的概念之一,使得不同的进程可以相互交换数据和进行协作。其中,共享内存是一种高效的进程间通信机制,而内存映射(mmap)是实现共享内存的一种常见方法。 存储映射 I/O 是 一个磁盘文件 与 存储空间中的一个缓冲区相映射 。于是, 当从缓

    2024年02月13日
    浏览(44)
  • 【Linux】进程间通信之共享内存

    共享内存比管道快哦~ 文章目录 前言 一、共享内存的实现原理 二、实现共享内存的代码 总结 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的

    2024年02月03日
    浏览(50)
  • Linux--进程间的通信-共享内存

    前文: Linux–进程间的通信-匿名管道 Linux–进程间的通信–进程池 Linux–进程间的通信-命名管道 对于两个进程,通过在内存开辟一块空间(操作系统开辟的),进程的虚拟地址通过页表映射到对应的共享内存空间中,进而实现通信 ; 特点和作用: 高效性: 共享内存是一种

    2024年04月26日
    浏览(42)
  • 【hello Linux】进程间通信——共享内存

    目录 前言: 1. System V共享内存 1. 共享内存的理解 2. 共享内存的使用步骤 3. 共享内存的使用         1. 共享内存的创建         查看共享内存         2. 共享内存的释放         3. 共享内存的挂接         4. 共享内存的去挂接 4. 共享内存的使用示例 1. 两进

    2024年02月01日
    浏览(105)
  • 【Linux】进程间的通信之共享内存

    利用 内存共享 进行进程间的通信的原理其实分为以下几个步骤: 在物理内存中创建一块共享内存。 将共享内存链接到要通信的进程的页表中,并通过页表进行进程地址空间的映射。 进程地址空间映射完毕以后返回首个虚拟地址,以便于进程之间进行通信。 根据共享内存的

    2024年02月09日
    浏览(50)
  • C# .Net 多进程同步 通信 共享内存

    节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。         内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作系统中地位相当。实际上,任何想要共享数据的通信模型都会在幕后使用它。   

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包