共享内存

今天写的一个共享类,通过共享内存来实现进程间的通信,写的不完整的请改正,下面贴代码

#pragma once
/************************************************************************/
/* 文件名 :     MemMap.h
	创建时间:[29/11/2012] 
    作者:		J-K                                                         */
/************************************************************************/
// CMemMap 命令目标

class CMemMap : public CObject
{
private:
	BOOL m_bReadOnly;

	HANDLE m_hMapping;
	//互斥手段
	HANDLE m_hMutexLock;
	//同步手段
	HANDLE m_hNotifyEvent;
	
	//命名内核对象名字
	CString m_strMapName;
	CString m_strMutexName;
	CString m_strEventName;
	
	//内存地址
	LPBYTE m_lpData;
	DWORD m_dwLength;
	DWORD m_dwErrorCode;
public:
	CMemMap(CString strMapName, DWORD dwLen, BOOL bReadOnly);
	virtual ~CMemMap();
	//写进程
	BOOL MapMemory();
	//读进程
	BOOL MapExistingMemory();
	BOOL UnMap();
	BOOL Flush();
	//同步
	void Lock();
	void UnLock();
	void SetNotify();
	//访问
	CString CreateMutexName();
	CString CreateEventName();
	LPBYTE GetAddress(size_t pos);
	HANDLE GetNotifyEvt();
	void GetLastErrorDiscrib();
#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
	virtual void AssertValid() const;
#endif // _DEBUG

};

// MemMap.cpp : 实现文件
//

#include "stdafx.h"
#include "MemMap.h"

// CMemMap

CMemMap::CMemMap(CString strMapName, DWORD dwLen, BOOL bReadOnly)
	:m_hMutexLock(NULL),
	 m_hNotifyEvent(NULL),
	 m_strMapName(strMapName),
	 m_lpData(NULL),
	 m_dwLength(dwLen),
	 m_bReadOnly(bReadOnly),
	 m_dwErrorCode(0)
{
	m_strMutexName = _T("");
	m_strEventName = _T("");
}

CMemMap::~CMemMap()
{
	UnMap();
}

// CMemMap 成员函数
BOOL CMemMap::MapMemory()
{
	HANDLE hFile = INVALID_HANDLE_VALUE;

	//这里的读写权限是面向访问此块内存的进程
	//如果设为只读则所有进程只有只读权限
	DWORD dwprotect = m_bReadOnly? PAGE_READONLY :PAGE_READWRITE;
	m_hMapping = CreateFileMapping(hFile, NULL, dwprotect, 0, m_dwLength, m_strMapName); 
	if (m_hMapping == NULL)
	{
		m_dwErrorCode = GetLastError();
		//TRACE("Warnning: Mapped the memory file failed!Error Code:%d\n", m_dwErrorCode);
		return FALSE;
	}

	DWORD dwDesiredAccess = m_bReadOnly?FILE_MAP_READ:FILE_MAP_WRITE;
	m_lpData = (LPBYTE)MapViewOfFile(m_hMapping, dwDesiredAccess, 0, 0, 0);
	if (m_lpData != NULL)
	{
		//防止访问的字符为宽字符
		m_lpData[m_dwLength] = 0;
		m_lpData[m_dwLength+1] = 0;
	}
	else
	{
		m_dwErrorCode = GetLastError();
		return FALSE;
	}
	//创建互斥锁
	CString strMutexName = CreateMutexName();
	m_hMutexLock = CreateMutex(NULL, FALSE, strMutexName);

	//通知事件
	CString strEvtName = CreateEventName();
	m_hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, strEvtName);

	if ((!m_hMutexLock) || (!m_hNotifyEvent))
	{
		m_dwErrorCode = GetLastError();
		return FALSE;
	}
	return (m_lpData !=NULL);
}

//打开并访问共享区
BOOL CMemMap::MapExistingMemory()
{
	DWORD dwDesiredAccess = (!m_bReadOnly)?FILE_MAP_WRITE:FILE_MAP_READ;

	m_hMapping = OpenFileMapping(dwDesiredAccess, FALSE, m_strMapName);
	if (m_hMapping == NULL)
	{
		//TRACE("Warnning: Open the File mapping failed! Error Code:%d\n", GetLastError());
		m_dwErrorCode = GetLastError();
		return FALSE;
	}
	m_lpData = (LPBYTE)MapViewOfFile(m_hMapping, dwDesiredAccess, 0, 0, m_dwLength);
	if (m_lpData == NULL)
	{
		m_dwErrorCode = GetLastError();
		return FALSE;
	}
	CString strMutexName = CreateMutexName();
	m_hMutexLock = OpenMutex(SYNCHRONIZE, FALSE, strMutexName);

	CString strEvtName = CreateEventName();
	m_hNotifyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, strEvtName);

	if ((!m_hMutexLock) || (!m_hNotifyEvent))
	{
		m_dwErrorCode = GetLastError();
		return FALSE;
	}
	return (m_lpData != NULL);
}

//进程同步访问
void CMemMap::Lock()
{
	::WaitForSingleObject(m_hMutexLock, INFINITE);
}

void CMemMap::UnLock()
{
	::ReleaseMutex(m_hMutexLock);
}
void CMemMap::SetNotify()
{
	SetEvent(m_hNotifyEvent);
}

BOOL CMemMap::Flush()
{
	if (m_lpData == NULL)
	{
		return FALSE;
	}
	return FlushViewOfFile(m_lpData, 0);
}

CString CMemMap::CreateMutexName()
{
	return m_strMutexName + _T("MUTEX");
}

CString CMemMap::CreateEventName()
{
	return m_strEventName + _T("NOTIFYEVENT");
}

BOOL CMemMap::UnMap()
{
	//解锁
	UnLock();

	if (m_lpData != NULL)
	{
		FlushViewOfFile(m_lpData, 0);
		UnmapViewOfFile(m_lpData);
		m_lpData = NULL;
	}
	if (m_hMapping != NULL)
	{
		CloseHandle(m_hMapping);
		m_hMapping = NULL;
	}
	if (m_hMutexLock != NULL)
	{
		CloseHandle(m_hMutexLock);
		m_hMutexLock = NULL;
	}
	if (m_hNotifyEvent != NULL)
	{
		CloseHandle(m_hNotifyEvent);
		m_hNotifyEvent = NULL;
	}
	m_bReadOnly = TRUE;
	m_strMapName = _T("");
	m_dwLength = 0;
	return TRUE;
}

LPBYTE CMemMap::GetAddress(size_t pos)
{
	//安全监测
	if (pos >= m_dwLength || pos <0)
	{
		return NULL;
	}
	return m_lpData+pos;
}

HANDLE CMemMap::GetNotifyEvt()
{
	return m_hNotifyEvent;
}

//获取详细错误描述
void CMemMap::GetLastErrorDiscrib()
{
	TCHAR *Temp = new TCHAR[200];

	LPVOID lpMsgBuf;

	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		m_dwErrorCode,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
		);
#ifdef UNICODE
	swprintf(Temp, _T("WARNING: Failed with the following error: %s\n"), lpMsgBuf);
#else
	sprintf(Temp, "WARNING: Failed with the following error: %s\n", lpMsgBuf); 
#endif
	MessageBox(NULL, Temp, _T("Application Error"), MB_ICONSTOP);
	LocalFree(lpMsgBuf);
	delete[] Temp;
}

//调试输出各项参数
#ifdef _DEBUG
void CMemMap::Dump(CDumpContext& dc) const
{
	CObject::Dump(dc);

	// TODO: 在此添加专用代码和/或调用基类
	CString sText;
	sText.Format(_T("m_hMapping=0x%08x\n"), m_hMapping);
	dc << sText;
	sText.Format(_T("m_bReadOnly=%d\n"), m_bReadOnly);
	dc << sText;
	sText.Format(_T("m_lpData=0x%08x\n"), m_lpData);
	dc << sText;
	sText.Format(_T("m_hMutexLock=0x%08x\n"), m_hMutexLock);
	dc << sText;
	sText.Format(_T("m_NotifyEvent=0x%08x\n"), m_hNotifyEvent);
	dc<<sText;
	sText.Format(_T("m_dwLength=%d\n\n"), m_dwLength);
	dc << sText;
}
#endif

//判断所有参数是否正确
#ifdef _DEBUG
void CMemMap::AssertValid() const
{
	CObject::AssertValid();

	// TODO: 在此添加专用代码和/或调用基类
	ASSERT(m_hMutexLock != NULL);
	ASSERT(m_hMapping != NULL);
	ASSERT(m_hNotifyEvent != NULL);
	ASSERT(m_lpData != NULL);
}
#endif

测试代码 demo.zip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值