一个共享内存封装类的源码

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



你可能感兴趣的:(一个共享内存封装类的源码)