进程间通讯---共享内存

核心函数:

HANDLE 
WINAPI
CreateFileMappingW(
    _In_ HANDLE hFile,
    _In_opt_ LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
    _In_ DWORD flProtect,
    _In_ DWORD dwMaximumSizeHigh,
    _In_ DWORD dwMaximumSizeLow,
    _In_opt_ LPCWSTR lpName
    );

HANDLE
WINAPI
OpenFileMappingW(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ LPCWSTR lpName
    );

LPVOID
WINAPI
MapViewOfFile(
    _In_ HANDLE hFileMappingObject,
    _In_ DWORD dwDesiredAccess,
    _In_ DWORD dwFileOffsetHigh,
    _In_ DWORD dwFileOffsetLow,
    _In_ SIZE_T dwNumberOfBytesToMap
    );

在处理两个进程之间的通讯问题上,我采用了数据包区分的情况。两个进程中都开启接受线程,每隔一段时间查看共享内存中的值,当符合A的时候A拿走,符合B的时候B拿走。

A进程核心代码:

#include "stdafx.h"
#include "FileMapping.h"


FileMapping::FileMapping(void)
{
	//使用文件映射技术
	m_hMapFile = CreateFileMapping(
		INVALID_HANDLE_VALUE,
		NULL,PAGE_READWRITE,0,16,
		L"ROOTkit");
	if(NULL == m_hMapFile || INVALID_HANDLE_VALUE == m_hMapFile)
		MessageBox(NULL,L"文件映射创建失败",L"提示",NULL); 
	//映射文件试图到调用进程的地址空间
	m_pBuf = MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,
		0,0,5); //创建5个字节的空间,1个字节位标志,剩下四个为传输信息。
	//进行交流
	if(NULL == m_pBuf) //创建失败
		MessageBox(NULL,L"空间申请失败",L"提示",NULL);

	//创建接受线程
	CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,this,0,NULL);
}


FileMapping::~FileMapping(void)
{
	CloseHandle(m_hMapFile);
}

bool FileMapping::SendInfo(int seInfo)
{
	//第一个字节为1
	//对信息进行封装
	((byte*)m_pBuf)[0] = 1;
	//向缓冲区中写入信息
	*(int*)&(((byte*)m_pBuf)[1]) = seInfo;
	return TRUE;
}

DWORD WINAPI FileMapping::RecvInfo()
{
	while (true)
	{
		int sign = ((byte*)m_pBuf)[0];
		int PhysicsAddress = 0;
		if( 2 == sign )
		{
			int PhysicsAddress = *(int*)&(((byte*)m_pBuf)[1]);
			ZeroMemory(m_pBuf,5);
			printf("实际的物理地址:%x\n",PhysicsAddress);
			MessageBox(NULL,L"FileMapping",NULL,NULL);
		}
		Sleep(1000);
	}
}

DWORD WINAPI FileMapping::ThreadProc(LPVOID lpThreadParameter)
{
	((FileMapping*)lpThreadParameter)->RecvInfo();
	return true;
}

进程B核心代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include<windows.h>
PVOID g_pBuf;

BOOL SendInfo(int seInfo)
{
	//第一个字节为2
	//对信息进行封装
	((BYTE*)g_pBuf)[0] = 2;
	//向缓冲区中写入信息
	*(int*)&(((BYTE*)g_pBuf)[1]) = seInfo;
	return true;
}
bool RecvInfo(DWORD lp)
{
	while (true)
	{
		int sign = ((BYTE*)g_pBuf)[0];
		int PhysicsAddress = 0;
		if( 1 == sign )
		{
			int PhysicsAddress = *(int*)&(((BYTE*)g_pBuf)[1]);  //将接受到的虚拟地址转换成物理地址
			MessageBox(NULL,L"DLL",NULL,NULL);
			ZeroMemory(g_pBuf,5);
			SendInfo(0x12345678);
		}
		Sleep(1000);
	}
	return true;
}
BOOL Chat()
{
	//打开一个现成的文件映射对象
	HANDLE hMapFile = OpenFileMapping(
		FILE_MAP_ALL_ACCESS,
		FALSE,
		L"ROOTkit");
	if(NULL == hMapFile || INVALID_HANDLE_VALUE == hMapFile)
		MessageBox(NULL,L"文件映射创建失败",L"提示",NULL);
	g_pBuf = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,5);
	if(NULL == g_pBuf)
		MessageBox(NULL,L"空间申请失败",L"提示",NULL);
	//创建一个接受线程
	CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RecvInfo,NULL,0,NULL);
	return TRUE;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Qt中,线程通讯可以使用共享内存来实现。共享内存是一种跨进程共享数据的机制,可以在不同的线程传递数据。 Qt提供了QSharedMemory类来操作共享内存。下面是一个使用共享内存进行线程通讯的示例: ```cpp // 创建一个共享内存对象 QSharedMemory sharedMemory; // 设置共享内存的名称 sharedMemory.setKey("MySharedMemory"); // 在一个线程中写入数据到共享内存 if (sharedMemory.create(1024)) { sharedMemory.lock(); char* data = static_cast<char*>(sharedMemory.data()); // 在这里写入数据到共享内存 // 注意:要确保多个线程对共享内存的访问是互斥的,可以使用QMutex来实现互斥访问 sharedMemory.unlock(); } // 在另一个线程中读取共享内存中的数据 if (sharedMemory.attach()) { sharedMemory.lock(); char* data = static_cast<char*>(sharedMemory.data()); // 在这里读取共享内存中的数据 sharedMemory.unlock(); sharedMemory.detach(); } ``` 在上面的示例中,我们创建了一个名为"MySharedMemory"的共享内存对象,并设置了它的大小为1024字节。然后,在一个线程中写入数据到共享内存中,另一个线程则可以读取共享内存中的数据。 需要注意的是,在多个线程对共享内存进行读写时,需要确保访问的互斥性,以避免数据竞争。可以使用QMutex或其他同步机制来实现互斥访问。 另外,还可以使用信号与槽机制来实现线程通讯。Qt提供了QObject::moveToThread()方法,可以将一个QObject对象移动到指定的线程中,从而实现线程的信号与槽的连接。这种方式相对于共享内存来说更加方便和安全。 希望以上信息能对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值