今天写的一个共享类,通过共享内存来实现进程间的通信,写的不完整的请改正,下面贴代码
#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