Win32 共享内存

CFileMappingHelper.h

#pragma once
#include 
#include 
#include 
#include 
#include 

#pragma warning(disable:4200)

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

class CFileMappingHelper
{
public:

    CFileMappingHelper();
    ~CFileMappingHelper();

    //删除拷贝构造与赋值重载
    CFileMappingHelper(const CFileMappingHelper&) = delete;
    CFileMappingHelper& operator = (const CFileMappingHelper&) = delete;

    //
    // @brief: 初始化一个文件映射
    // @param: strName    文件映射名
    // @param: strMutex   互斥锁名
    // @param: dwSize     缓冲大小
    // @ret: bool
    bool Initialize(
        LPCTSTR strName = nullptr, 
        LPCTSTR strMutex = nullptr, 
        DWORD dwSize = 4096
    );

    //
    // @brief: 反初始化
    // @param: 无
    // @ret: void
    void Uninitialize();

    //
    // @brief: 是否已初始化
    // @param: 无
    // @ret: bool           初始化与否
    bool IsInitialized() const;

    //
    // @brief: 获取文件映射容量
    // @ret: DWORD          文件映射容量
    DWORD GetCapacity() const;

    //
    // @brief: 写入文件映射
    // @param: lpData       要写入数据
    // @param: dwSize       写入长度
    // @ret: bool           操作成功与否
    bool Write(LPCVOID lpData, DWORD dwSize);

    //
    // @brief: 读取文件映射
    // @param: lpData       读入的缓冲
    // @param: dwSize       缓冲长度
    // @param: lpBytesRead  成功读取的长度
    // @ret: bool           操作成功与否
    bool Read(LPVOID lpData, DWORD dwSize, LPDWORD lpBytesRead = nullptr);

private:

    HANDLE m_hFileMapping = nullptr;
    LPTSTR m_hData = nullptr;
    HANDLE m_hMutex = nullptr;
    bool m_bInit = false;
};

CFileMappingHelper.cpp

#include "CFileMappingHelper.h"

typedef struct _FILE_MAPPING_DATA
{
    DWORD dwCapacity = 0;       //最大容量
    DWORD dwPid = 0;            //进程ID
    DWORD dwSize = 0;           //数据大小
    BYTE Data[0];               //数据内容
}FILE_MAPPING_DATA, * PFILE_MAPPING_DATA;

CFileMappingHelper::CFileMappingHelper()
    :
    m_hFileMapping(nullptr),
    m_hData(nullptr),
    m_hMutex(nullptr),
    m_bInit(false)
{

}

CFileMappingHelper::~CFileMappingHelper()
{
    Uninitialize();
}

bool CFileMappingHelper::Initialize(
    LPCTSTR strName/* = nullptr*/,
    LPCTSTR strMutex/* = nullptr*/,
    DWORD dwSize/* = 4096*/
)
{
    SECURITY_ATTRIBUTES sa = { 0 };
    SECURITY_DESCRIPTOR sd = { 0 };
    bool isSuccess = false;
    bool isFirstCreate = false;

    if (m_bInit)
    {
        return true;
    }

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = FALSE;
    sa.lpSecurityDescriptor = &sd;

    (void)::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    (void)::SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);

    do
    {
        m_hMutex = ::CreateMutex(&sa, FALSE, strMutex);
        if (nullptr == m_hMutex)
        {
            break;
        }

        m_hFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, dwSize + sizeof(FILE_MAPPING_DATA), strName);
        if (nullptr == m_hFileMapping)
        {
            break;
        }
        if ((nullptr != m_hFileMapping) && (ERROR_ALREADY_EXISTS != ::GetLastError()))
        {
            isFirstCreate = true;
        }

        m_hData = (LPTSTR)::MapViewOfFile(m_hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
        if (nullptr == m_hData)
        {
            break;
        }

        //首次创建, 设置信息
        if (isFirstCreate)
        {
            PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
            pData->dwCapacity = dwSize;
            pData->dwPid = ::GetCurrentProcessId();
        }

        isSuccess = true;

    } while (false);

    if (!isSuccess)
    {
        Uninitialize();
    }

    m_bInit = isSuccess;

    return isSuccess;
}

void CFileMappingHelper::Uninitialize()
{
    if (false == m_bInit)
    {
        return;
    }

    if (m_hData)
    {
        ::UnmapViewOfFile(m_hData);
        m_hData = nullptr;
    }

    if (m_hFileMapping)
    {
        ::CloseHandle(m_hFileMapping);
        m_hFileMapping = nullptr;
    }

    if (m_hMutex)
    {
        ::CloseHandle(m_hMutex);
        m_hMutex = nullptr;
    }

    m_bInit = false;
}

bool CFileMappingHelper::IsInitialized() const
{
    return m_bInit;
}

bool CFileMappingHelper::Write(LPCVOID lpData, DWORD dwSize)
{
    bool isSuccess = false;
    DWORD dwWait = WAIT_OBJECT_0;

    if ((nullptr == m_hMutex) || (nullptr == m_hData) || (nullptr == lpData) || (0 == dwSize))
    {
        return false;
    }

    PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);

    do
    {
        dwWait = ::WaitForSingleObject(m_hMutex, INFINITE);
        if (WAIT_OBJECT_0 != dwWait)
        {
            break;
        }

        if (dwSize <= pData->dwCapacity)
        {
            ::memcpy_s(pData->Data, pData->dwCapacity, lpData, dwSize);
            pData->dwSize = dwSize;
            isSuccess = true;
        }

    } while (false);

    ::ReleaseMutex(m_hMutex);

    return isSuccess;
}

bool CFileMappingHelper::Read(LPVOID lpData, DWORD dwSize, LPDWORD lpBytesRead/* = nullptr*/)
{
    bool isSuccess = false;
    DWORD dwWait = WAIT_OBJECT_0;

    if ((nullptr == m_hMutex) || (nullptr == m_hData) || (nullptr == lpData) || (0 == dwSize))
    {
        return false;
    }

    PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);

    do
    {
        dwWait = ::WaitForSingleObject(m_hMutex, INFINITE);
        if (WAIT_OBJECT_0 != dwWait)
        {
            break;
        }

        if (dwSize <= (pData->dwCapacity))
        {
            ::memcpy_s(lpData, dwSize, pData->Data, pData->dwSize);
            if (nullptr != lpBytesRead)
            {
                *lpBytesRead = pData->dwSize;
            }
            isSuccess = true;
        }

    } while (false);

    ::ReleaseMutex(m_hMutex);

    return isSuccess;
}

DWORD CFileMappingHelper::GetCapacity() const
{
    if ((nullptr == m_hMutex) || (nullptr == m_hData))
    {
        return 0;
    }

    PFILE_MAPPING_DATA pData = reinterpret_cast(m_hData);
    return pData->dwCapacity;
}

你可能感兴趣的:(C++,Win32,windows,c++,Win32)