(转载请注明原文地址: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); }
#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