C++(MFC)共享内存

1.MessageShm.h

#pragma once
#include <atlstr.h>
#include <list>
class MessageShm
{ 
public:
    bool CreateA1(CString Name, int Size);
    bool Send(CString Name, int Size, CString Data);
    bool CreateA2(CString Name, int Size);
    CString Get(CString Name, int Size);
    bool RingSend(CString Name, int Size, CString Data); //响应发送
};

2.MessageShm.cpp

#include "pch.h" 
#include "MessageShm.h"  
LPVOID PointerA1 = NULL;
HANDLE HandleA1 = NULL;
CString Buf;     //发送失败的缓存

/// <summary>
/// 打开或创建
/// </summary>
/// <param name="Name">名称</param>
/// <param name="Size">低位文件大小</param>
/// <returns></returns>
bool  MessageShm::CreateA1(CString Name, int Size) 
{
    HandleA1 = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, Name);    //打开共享内存
    if (HandleA1 == NULL)
    {
        HandleA1 = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, Size, Name);//创建共享内存
        if (HandleA1 == NULL)
            return false; 
    }
    PointerA1 = MapViewOfFile(HandleA1, FILE_MAP_ALL_ACCESS, 0, 0, 0);   //映射到本进程的地址空间
    if (PointerA1 == NULL)
        return false;
    return true;
}
/// <summary>
/// 关闭共享内存
/// </summary>
/// <returns></returns>
UINT MessageShm::Close()
{
    if (!UnmapViewOfFile(PointerA1))   // 释放 
        return 2; 
    if (!CloseHandle(HandleA1))  // 关闭内存映射文件对象句柄  
        return 1; 
    return 0;
}
/// <summary>
/// 写入
/// </summary>
/// <param name="Name">名称</param>
/// <param name="Size">低位文件大小</param>
/// <param name="Data">写入数据</param>
/// <returns></returns>
void MessageShm::Send(CString Name, int Size, CString Data)
{ 
        byte* pByte = (byte*)PointerA1;
        USES_CONVERSION;
        strcpy_s((char*)pByte, strlen(W2A(Data))+1, W2A(Data)); 
}
/// <summary>
/// 读取
/// </summary>
/// <param name="Name">名称</param>
/// <param name="Size">低位文件大小</param>
/// <returns></returns>
CString MessageShm::Get(  CString Name, int Size)
{
    CString StrMsg;  
        byte* pByte = (byte*)PointerA1;
        CString data(pByte);
        if (PointerA1 !=0 && data != "" && data != "OK")
        {
            StrMsg.Format(L"读取共享内存:%s", data.GetString()); 
        } 
    return StrMsg;
}

/// <summary>
/// 有反馈的写入,未收到反馈则存起来下次再发
/// </summary>
/// <param name="Name">名称</param>
/// <param name="Size">低位文件大小</param>
/// <param name="Data">写入内容</param>
/// <returns></returns>
bool MessageShm::RingSend(CString Name, int Size, CString Data) //写入
{
    if (CreateA1(Name, Size))
    { 
        byte* pByte = (byte*)PointerA1;
        CString data(pByte);
        if (data == "OK")
        { 
            Send(Name, Size, Buf + Data); //写入
            Buf = "";
        }
        else
            Buf += Data;     //发送失败缓存 
    }
    return true;
}

3.读取

hMessageShm.CreateA1(L"test",4096);		//打开或创建共享内存
void TestDlg::GetMessage_Str()
{  
       CString StrMsg = hMessageShm. Get(L"test", 4096);
       if (StrMsg != L"") 
       { 
       		Printf(StrMsg);
       }
} 

4.一直读取

4.1.TestDlg.h

class TestDlg : public CDialogEx    
{ 
private:
	MessageShm hMessageShm;
    unsigned int  Thread15 = 15;		//读共享内存线程ID
    HANDLE* hThread15{};                //读共享内存线程句柄
public:
    BOOL GetMessage_Str();       		//读取
    void GetMessageThread();			//读取共享内存线程
}

4.2.TestDlg.cpp

	//启动页面时:
	if (hMessageShm.CreateA1(L"test",4096)) //打开或创建共享内存
	{
		GetMessageThread();             //读取共享内存
	}
void TestDlg::GetMessage_Str()
{
    while (1)
    {
       Sleep(1);
       CString StrMsg = hMessageShm. Get(L"test", 4096);
       if (StrMsg != L"") { Printf(StrMsg); }
    }
}

static unsigned int __stdcall Thread11(void* pUser)
{
    TestDlg* pThis = (TestDlg*)pUser;
    if (pThis)
    {
        pThis->GetMessage_Str();//读共享内存
    }
    return 0;
}

void TestDlg::GetMessageThread()
{
    hThread15 = (HANDLE*)_beginthreadex(NULL, 0, Thread11, this, CREATE_SUSPENDED, &Thread15);
    ::SetThreadPriority(hThread15, THREAD_PRIORITY_LOWEST);    //优先级
    ::ResumeThread(hThread15);
    if (NULL == hThread15)
    {
        ShowErrorMsg(TEXT("开启共享内存读取线程失败! "), 0);
    }
}

5.写入

	MessageShm hMessageShm;
	void TestDlg::OnInitDialog
	{
		hMessageShm.CreateA1(L"test",4096);		//打开或创建共享内存
	}
	void TestDlg::Button1()
	{
    	CString StrMsg; 
    	StrMsg.Format(L"进程A写入测试"); 
    	hMessageShm.Send(L"test", 4096, StrMsg);//写入
    }

6.有反馈的写入

	MessageShm hMessageShm;
	CString StrMsg; 
	StrMsg.Format(L"进程A写入测试"); 
	hMessageShm.CreateA1(L"test",4096);		//打开或创建共享内存
    hMessageShm.RingSend(L"test", 4096, StrMsg);//写入

版权声明:本文为qq_35831134原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。