I. knowledge points
The following functions are mainly used, and the specific meaning of parameters can be Baidu
1.CreateFileMapping,OpenFileMapping,MapViewOfFile
2.CreateEvent,SetEvent,ResetEvent,WaitForSingleObject
Two, function
The logic is simple:
1. First open the shared memory according to the name. If it fails to open, create it. Then call MapViewOfFile to get the address of shared memory.
2. start a thread, use event to detect whether there is data in shared memory, if there is data, read it, then call data processing function to process.
Code:
ShareMemory.h
#ifndef SHAREMEMORY_H #define SHAREMEMORY_H #include <string> #include <thread> #include <memory> #include "Windows.h" class ShareMemory { public: ShareMemory(std::wstring strKey, unsigned int nSize = 1024); ~ShareMemory(); void registeReceiver(std::function<void(char *)> pfunReceiver); void writeData(char *data, int nLength); private: void readData(); private: std::shared_ptr<std::thread> m_ptrReadThread; bool m_bThreadRunning = true; HANDLE m_hMapFile = nullptr; LPVOID m_buffer = nullptr; std::function<void(char *)> m_pfunReceiver = nullptr; std::wstring m_strUniqueId; HANDLE m_writeEvent = nullptr; }; #endif
ShareMemory.cpp
#include "stdafx.h" #include "ShareMemory.h" #include <iostream> ShareMemory::ShareMemory(std::wstring strKey, unsigned int nSize) { m_strUniqueId = std::move(strKey); m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, m_strUniqueId.c_str()); if (!m_hMapFile) { m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, nSize, m_strUniqueId.c_str()); } if (m_hMapFile) { m_buffer = MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, nSize); if (!m_buffer) { CloseHandle(m_hMapFile); } else { std::wstring strWriteKey = m_strUniqueId; strWriteKey.append(L"_write"); m_writeEvent = CreateEvent(NULL, TRUE, FALSE, strWriteKey.c_str()); memset(m_buffer, 0, nSize); m_ptrReadThread = std::make_shared<std::thread>(std::bind(&ShareMemory::readData, this)); } } } ShareMemory::~ShareMemory() { if (m_buffer) { UnmapViewOfFile(m_buffer); m_buffer = nullptr; } if (m_hMapFile) { CloseHandle(m_hMapFile); m_hMapFile = nullptr; } if (m_writeEvent) { CloseHandle(m_writeEvent); m_writeEvent = nullptr; } } void ShareMemory::registeReceiver(std::function<void(char *)> pfunReceiver) { m_pfunReceiver = pfunReceiver; } void ShareMemory::writeData(char *data, int nLength) { if (m_writeEvent) { memcpy(m_buffer, data, nLength); SetEvent(m_writeEvent); } } void ShareMemory::readData() { if (!m_writeEvent) { return; } while (m_bThreadRunning) { DWORD dwWaitResult = WaitForSingleObject(m_writeEvent, INFINITE); switch (dwWaitResult) { // Event object was signaled case WAIT_OBJECT_0: { if (m_pfunReceiver) { char *data = (char*)m_buffer; int nLen = strlen(data); m_pfunReceiver(data); memset(m_buffer, 0, nLen); ResetEvent(m_writeEvent); } break; } default: std::cout<<"Wait error :" << GetLastError()<<std::endl; break; } } }
Write data process
int main(int *argc, char *argv[]) { ShareMemory sm(L"mysharememory"); while (true) { char in[100]; std::cin >> in; sm.writeData(in, strlen(in)); } system("pause"); return 0; }
Read data process
int main(int *argc, char *argv[]) { ShareMemory sm(L"mysharememory"); std::string i = std::string(argv[1]); sm.registeReceiver([](char *data) { std::cout << data << std::endl; }); system("pause"); return 0; }
Three, problems
The logic of this code is relatively simple. It has realized the data reading and writing of shared memory, but there are still many scenarios that have not been processed. Next, we will modify it