Windows下共享内存示例

最近学习一下共享内存,从别的地方转过来的代码,记录一下,这份代码分三个工程,ShareMemory(共享内存类库,已封装成DLL),Client(测试客户端进程), Server(测试服务端进程),不多说,直接上代码:

ShareMemory.h文件:

// ShareMemory.h: interface for the CShareMemory class.
//
//

#if !defined(AFX_SHAREMEMORY_H__0B0797DE_D3D1_4CCC_976B_44F87546607A__INCLUDED_)
#define AFX_SHAREMEMORY_H__0B0797DE_D3D1_4CCC_976B_44F87546607A__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifdef SHAREMEMORY_EXPORTS
#define SHAREMEMORY_EXPORT		__declspec(dllexport)
#else
#define SHAREMEMORY_EXPORT		__declspec(dllimport)
#endif

#include <windows.h>

class SHAREMEMORY_EXPORT CShareMemory  
{
public:
	VOID Unlock();
	BOOL IsLocked();
	LPVOID Lock(DWORD dwWaitTimeout=INFINITE);
	BOOL IsValid();
	DWORD GetBytes();
	VOID Close();
	BOOL Open(LPCTSTR szName);
	BOOL Create(LPCTSTR szName, DWORD dwBytes);
	CShareMemory();
	virtual ~CShareMemory();

protected:
	DWORD m_dwBytes;
	HANDLE m_hFileMap;
	BOOL m_bLocked;
	LPVOID m_pData;
	HANDLE m_hFile;
	HANDLE m_hMutex;
};

#endif // !defined(AFX_SHAREMEMORY_H__0B0797DE_D3D1_4CCC_976B_44F87546607A__INCLUDED_)


ShareMemory.cpp文件:

// ShareMemory.cpp: implementation of the CShareMemory class.
//
//

#include "ShareMemory.h"
#include <stdio.h>

//
// Construction/Destruction
//

CShareMemory::CShareMemory()
{
	m_hFile=INVALID_HANDLE_VALUE;
	m_hMutex=NULL;
	m_pData=NULL;
	m_hFileMap=NULL;
	m_dwBytes=0;
}

CShareMemory::~CShareMemory()
{
	Close();
}

BOOL CShareMemory::Create(LPCTSTR szName, DWORD dwBytes)
{
	BOOL T=FALSE;
	char szBuf[MAX_PATH];
	LPCTSTR szFile;
	if(szName!=NULL&&dwBytes>0)
	{
		Close();
		szFile=tmpnam(szBuf);
		if(szFile!=NULL)
		{
			m_hFile=CreateFile(szFile, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
				NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL);
			if(m_hFile!=INVALID_HANDLE_VALUE)
			{
				if(SetFilePointer(m_hFile, dwBytes+sizeof(DWORD), NULL, FILE_BEGIN)!=-1)
				{
					if(SetEndOfFile(m_hFile))
					{
						m_hFileMap=CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, dwBytes+sizeof(DWORD), szName);
						if(m_hFileMap!=NULL)
						{
							m_dwBytes=dwBytes;
							m_pData=MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DWORD)+dwBytes);
							if(m_pData!=NULL)
							{
								*((LPDWORD)m_pData)=dwBytes;
								sprintf(szBuf, "Mutex<%s>", szName);
								m_hMutex=CreateMutex(NULL, FALSE, szBuf);
								if(m_hMutex!=NULL)
								{
									if(GetLastError()!=ERROR_ALREADY_EXISTS)
									{
										T=TRUE;
									}
								}
							}
						}
					}
				}
			}
			if(!T)
			{
				Close();
			}
		}
	}
	return T;
}

BOOL CShareMemory::Open(LPCTSTR szName)
{
	BOOL T=FALSE;
	char szBuf[MAX_PATH];
	if(szName!=NULL)
	{
		Close();
		m_hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
		if(m_hFileMap!=NULL)
		{
			sprintf(szBuf, "Mutex<%s>", szName);
			m_hMutex=OpenMutex(MUTEX_ALL_ACCESS, FALSE, szBuf);
			if(m_hMutex!=NULL)
			{
				m_pData=MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, m_dwBytes+sizeof(DWORD));
				if(Lock())
				{
					m_dwBytes=*((LPDWORD)m_pData);
					Unlock();
					if(m_dwBytes>0)
					{
						T=TRUE;
					}
				}
			}
		}
		if(!T)
		{
			Close();
		}
	}
	return T;
}

VOID CShareMemory::Close()
{
	if(m_bLocked)
	{
		Unlock();
	}
	if(m_pData!=NULL)
	{
		UnmapViewOfFile(m_pData);
		m_pData=NULL;
	}
	if(m_hFileMap!=NULL)
	{
		CloseHandle(m_hFileMap);
		m_hFileMap=NULL;
	}
	if(m_hFile!=INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hFile);
		m_hFile=INVALID_HANDLE_VALUE;
	}
	if(m_hMutex!=NULL)
	{
		CloseHandle(m_hMutex);
		m_hMutex=NULL;
	}
	m_dwBytes=0;
}

DWORD CShareMemory::GetBytes()
{
	return m_dwBytes;
}

BOOL CShareMemory::IsValid()
{
	return (m_hFileMap!=NULL&&m_hMutex!=NULL);
}

LPVOID CShareMemory::Lock(DWORD dwWaitTimeout)
{
	LPVOID pData=NULL;
	if(IsValid()&&m_pData!=NULL&&!m_bLocked)
	{
		if(WaitForSingleObject(m_hMutex, dwWaitTimeout)!=WAIT_TIMEOUT)
		{
			m_bLocked=TRUE;
		}
		if(m_bLocked)
		{
			pData=(LPVOID)((LPDWORD)m_pData+1);
		}
	}
	return pData;
}

BOOL CShareMemory::IsLocked()
{
	return m_bLocked;
}

VOID CShareMemory::Unlock()
{
	if(m_bLocked)
	{
		ReleaseMutex(m_hMutex);
		m_bLocked=FALSE;
	}
}




Server.cpp:  为了增加可读性,加了一些注释说明。

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include "ShareMemory.h"

#pragma comment(lib, "ShareMemory.lib")

void main()
{
	//共享内存对象
	CShareMemory sm;
	char ch;
	//创建共享内存
	if(sm.Create("Server", 1024))
	{
		LPSTR szMessage;
		printf("Share memory created!\n");

		//Lock后则可以写入数据了
		szMessage=(LPSTR)sm.Lock(100);

		//获取到的szMessage数据指针指向共享内存,任何时候都可以取到里面的数据,
		//szMessage数据在多线程中应用是否正常,还待验证
		if(szMessage)
		{
			//sprintf(szMessage, "Hellodsafmasdlkjfsda,mnf,dmsaf!");
			ch=szMessage[0];
			sm.Unlock();

			printf("Message has been delivered!\n");

			//while (true)
			//{
			//	char szInput[1024] = { 0 };
			//	std::cin >> szInput;

			//	szMessage = (LPSTR)sm.Lock(1);
			//	sprintf(szMessage, "%s", szInput);
			//	sm.Unlock(); 

			//}

			while (!kbhit())
			{
				if (szMessage != NULL)
				{
					if (szMessage[0] != ch)
					{
						ch = szMessage[0];
						//putchar(ch);
						printf("%s\n", szMessage);
					}
				}

			}
		}
		else
		{
			printf("Lock memory failed!\n");
			getch();
		}
		sm.Close();
	}
}


Client:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "ShareMemory.h"

#pragma comment(lib, "ShareMemory.lib")

void main()
{
	CShareMemory sm;
	if(sm.Open("Server"))
	{
		LPSTR szMessage;
		int ch;
		printf("Share memory opened! It's %d bytes.\n", sm.GetBytes());

		//客户端所取到的szMessage指针指向服务端进程申请的共享内存,
		//任何一方对这块内存操作,效果都是一样的。
		szMessage=(LPSTR)sm.Lock(300);
		if(szMessage!=NULL)
		{
			sm.Unlock();
			printf("Server message is: %s\n", szMessage);
			while(1)
			{
				ch=getch();
				if(ch==0x1b)
				{
					break;
				}
				putchar(ch);
				szMessage=(LPSTR)sm.Lock();
				if(szMessage!=NULL)
				{
					szMessage[0]=(char)ch;
					sm.Unlock();
				}

				printf("%s\n", szMessage);
			}
		}
		else
		{
			printf("Lock memory failed!\n");
			getch();
		}
		sm.Close();
	}
}

运行效果如下图:


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows下实现共享内存可以使用Windows API提供的函数来完成。下面是一个简单的示例代码: ```cpp #include <Windows.h> int main() { // 创建共享内存 HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // 使用无效的文件句柄创建匿名共享内存 NULL, // 默认安全属性 PAGE_READWRITE, // 可读写访问权限 0, // 共享内存大小(高32位) sizeof(int), // 共享内存大小(低32位) L"MySharedMemory"); // 共享内存名称 if (hMapFile == NULL) { // 处理错误 return 1; } // 将共享内存映射到进程的地址空间 LPVOID pBuf = MapViewOfFile( hMapFile, // 共享内存句柄 FILE_MAP_ALL_ACCESS, // 可读写访问权限 0, // 文件偏移(高32位) 0, // 文件偏移(低32位) sizeof(int)); // 映射的内存大小 if (pBuf == NULL) { // 处理错误 CloseHandle(hMapFile); return 1; } // 写入数据到共享内存 int* pData = (int*)pBuf; *pData = 123; // 从共享内存读取数据 int data = *pData; printf("Read data from shared memory: %d\n", data); // 解除映射并关闭共享内存句柄 UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; } ``` 这段代码创建了一个大小为 `sizeof(int)` 的共享内存,并将其映射到当前进程的地址空间中。然后,通过指针 `pData` 可以对共享内存中的数据进行读写操作。最后,使用 `UnmapViewOfFile` 解除映射并使用 `CloseHandle` 关闭共享内存句柄。 请注意,此示例仅仅是演示了共享内存的基本用法,实际使用中可能需要进行更多的错误处理和同步操作,以确保多个进程之间的数据一致性和安全性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值