(转载请注明原文地址:http://blog.csdn.net/while0/article/details/11358887)
本篇文章分享我以前实现的一个共享内存的封装类,它通过Windows的共享内存 API,以面向对象的形式提供一套接口,极大地方便使用。
该类提供以下接口:
1) 创建共享内存。
2)销毁共享内存。
3)对共享内存的数据读写。
4)提供互斥锁接口。
以下把源码贴出来,与大家分享。
文件SharedMemory.cpp:
#include "wtermin.h"
#include <assert.h>
#include "SharedMemory.h"
CSharedMemory::CSharedMemory()
{
m_strName.Empty();
m_nSize = -1;
m_hShmFile = NULL;
m_hMutex = NULL;
m_pData = NULL;
}
CSharedMemory::~CSharedMemory()
{
}
BOOL CSharedMemory::Create(LPCSTR lpName, int nSize, BOOL *pbExist)
{
HANDLE hShmFile, hMutex;
CString strShmName, strMutextName;
void* pData;
assert(m_hShmFile == NULL);
assert(m_pData == NULL);
//Create Mutext (name is like "MTX&ABCDEF")
strMutextName.Format("MTX&%s", lpName);
hMutex = CreateMutex(NULL, FALSE, strMutextName);
if (hMutex == NULL)
return FALSE;
//Create Shm (name is like "SHM&ABCDEF")
strShmName.Format("SHM&%s", lpName);
hShmFile = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, nSize, strShmName);
if (hShmFile == NULL)
{
CloseHandle(hMutex);
return FALSE;
}
if (pbExist != NULL)
{
*pbExist = (GetLastError() == ERROR_ALREADY_EXISTS) ? TRUE:FALSE;
}
pData = MapViewOfFile(hShmFile, FILE_MAP_WRITE, 0, 0, nSize);
if (pData == NULL)
{
CloseHandle(hMutex);
CloseHandle(hShmFile);
return FALSE;
}
m_strName = lpName;
m_nSize = nSize;
m_hShmFile = hShmFile;
m_hMutex = hMutex;
m_pData = pData;
return TRUE;
}
BOOL CSharedMemory::Destroy()
{
assert(m_hShmFile != NULL);
assert(m_pData != NULL);
if (!UnmapViewOfFile(m_pData))
{
WT_Error("CSharedMemory::Destroy(): UnmapViewOfFile lasterr=%d\n", GetLastError());
}
if (!CloseHandle(m_hShmFile))
{
WT_Error("CSharedMemory::Destroy(): CloseHandle1 lasterr=%d\n", GetLastError());
}
if (!CloseHandle(m_hMutex))
{
WT_Error("CSharedMemory::Destroy(): CloseHandle2 lasterr=%d\n", GetLastError());
}
m_strName.Empty();
m_nSize = -1;
m_hShmFile = NULL;
m_hMutex = NULL;
m_pData = NULL;
return TRUE;
}
BOOL CSharedMemory::IsExist(LPCSTR lpName)
{
HANDLE hShmFile;
CString strShmName;
strShmName.Format("SHM&%s", lpName);
hShmFile = OpenFileMapping(PAGE_NOACCESS, 0, strShmName);
if (hShmFile == NULL)
return FALSE;
CloseHandle(hShmFile);
return TRUE;
}
PBYTE CSharedMemory::GetData(LPCSTR lpName, int nSize)
{
HANDLE hShmFile;
CString strShmName;
strShmName.Format("SHM&%s", lpName);
hShmFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strShmName);
if (hShmFile == NULL)
return NULL;
PBYTE pData = (PBYTE)MapViewOfFile(hShmFile, FILE_MAP_ALL_ACCESS, 0, 0, nSize);
if (pData == NULL)
{
CloseHandle(hShmFile);
return NULL;
}
CloseHandle(hShmFile);
return pData;
}
BOOL CSharedMemory::SetData(PBYTE pData, int nOffset, int nSize)
{
assert(pData != NULL);
assert(m_pData != NULL);
if (nOffset < 0 || nOffset >= m_nSize)
return FALSE;
if (nSize == -1)
nSize = m_nSize - nOffset;
if (nSize < 0)
return FALSE;
if (nOffset + nSize > m_nSize)
return FALSE;
Lock();
memcpy((PBYTE)m_pData + nOffset, pData, nSize);
Unlock();
return TRUE;
}
PBYTE CSharedMemory::GetData(int nOffset)
{
return (PBYTE)m_pData + nOffset;
}
BOOL CSharedMemory::SetLong(DWORD dwData, int nOffset)
{
return SetData((PBYTE)&dwData, nOffset, sizeof(dwData));
}
DWORD CSharedMemory::GetLong(int nOffset)
{
DWORD dwData;
Lock();
dwData = *(DWORD*)GetData(nOffset);
Unlock();
return dwData;
}
BOOL CSharedMemory::SetString(CString strData, int nOffset, int nSize)
{
int nLen = 0;
if (nSize == -1)
nLen = strData.GetLength() + 1;
else
nLen = min(strData.GetLength() + 1, nSize);
if (nLen < 0)
return FALSE;
return SetData((PBYTE)(LPCSTR)strData, nOffset, nLen);
}
BOOL CSharedMemory::GetString(CString &strData, int nOffset)
{
int nLen = 0;
PBYTE pData = NULL;
Lock();
pData = GetData(nOffset);
while (*pData++ != '\0') nLen++;
Unlock();
if (nOffset + nLen + 1 > m_nSize)
return FALSE;
Lock();
strData.Format("%s", (LPCSTR)GetData(nOffset));
Unlock();
return TRUE;
}
BOOL CSharedMemory::Lock( )
{
if (WaitForSingleObject(m_hMutex, INFINITE) == WAIT_OBJECT_0)
return TRUE;
return FALSE;
}
BOOL CSharedMemory::Unlock( )
{
return ReleaseMutex(m_hMutex);
}
头文件SharedMemory.h
#ifndef __SHAREDMEMORY_H__
#define __SHAREDMEMORY_H__
class CSharedMemory
{
protected:
GString m_strName;
int m_nSize;
HANDLE m_hShmFile;
HANDLE m_hMutex;
PVOID m_pData;
public:
CSharedMemory();
virtual ~CSharedMemory();
BOOL Create(LPCSTR lpName, int nSize, BOOL *pbExist = NULL);
BOOL Destroy();
static BOOL IsExist(LPCSTR lpName);
static PBYTE GetData(LPCSTR lpName, int nSize);
BOOL SetLong(DWORD dwData, int nOffset = 0);
DWORD GetLong(int nOffset = 0);
BOOL SetString(GString strData, int nOffset = 0, int nSize = -1);
BOOL GetString(GString &strData, int nOffset = 0);
inline int GetSize() {return m_nSize;};
BOOL Lock( );
BOOL Unlock( );
BOOL SetData(PBYTE pData, int nOffset = 0, int nSize = -1);
PBYTE GetData(int nOffset = 0);
};
#endif