把之前代码整理下,封装了一个用于共享内存的类。
头文件:CShareMem.h
1 /* @CShareMem类用于内存映射文件,在进程间传输帧数据 */ 2 enum eDATATYPE { NONE_TYPE, FRAME_TYPE, STATUS_TYPE, INFO_TYPE, CMD_TYPE }; 3 class CShareMem 4 { 5 public: 6 enum EM_EVENS { EV_NONE, EV_READ_THIS, EV_WRITE_THIS, EV_READ_OTHER, EV_WRITE_OTHER, EV_TIMEOUT }; 7 public: 8 struct SM_MEMFLAG 9 { 10 enum eMemFlag{ ACT_NONE, ACT_READ, ACT_WRITE } eLastAction; 11 DWORD dwProcessId; 12 eDATATYPE eDataType; 13 UDPFrameData m_DataHead; 14 char m_DataBuff[BUFFER_SIZE]; // Text from client to server 15 }; 16 class SM_MEMPTR 17 { 18 public: 19 ~SM_MEMPTR(); 20 SM_MEMFLAG* m_pMemFlag; 21 private: 22 friend class CShareMem; 23 SM_MEMPTR(CShareMem&, SM_MEMFLAG*, SM_MEMFLAG::eMemFlag); 24 CShareMem& m_ShareMemory; 25 }; 26 // 27 CShareMem(CONST TCHAR* lpName = RZT_FRAME_RECV); 28 ~CShareMem(); 29 /* @ 使用这个函数获得内存映射的指针,可用于直接存放或读取数据 30 @ { std::auto_ptr<SM_MEMPTR> ptr = GetMemptr(SM_MEMFLAG::ACT_READ); use ptr .. } 31 */ 32 std::auto_ptr<SM_MEMPTR> GetMemptr(SM_MEMFLAG::eMemFlag eFlag) 33 { 34 return auto_ptr<SM_MEMPTR>(new SM_MEMPTR(*this, m_pMemFlag,eFlag)); 35 } 36 EM_EVENS WaitEvent(DWORD dwTimeOut); 37 void WaitEvent(EM_EVENS eEvent); 38 bool Read(UDPFrameData* pDataHead, char* pData, eDATATYPE* type = nullptr); 39 bool Write(UDPFrameData* pDataHead,const char* pData, eDATATYPE type = FRAME_TYPE); 40 private: 41 DWORD m_dwProcessId; 42 HANDLE m_hMemory; 43 HANDLE m_hMutex; 44 HANDLE m_hEvent; 45 SM_MEMFLAG* m_pMemFlag; 46 char * m_DataBuff; 47 UDPFrameData * m_DataHead; 48 };
实现文件:CShareMem.cpp
1 CShareMem::CShareMem(CONST TCHAR* lpName):m_hMemory(NULL), m_hMutex(NULL), m_hEvent(NULL) 2 { 3 m_dwProcessId = GetCurrentProcessId(); 4 if (!lpName) 5 { 6 lpName = _T("SHARE.MEMORY"); 7 } 8 m_hMemory = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUFFER_SIZE, lpName); 9 if (::GetLastError() == ERROR_ALREADY_EXISTS) 10 { 11 m_hMemory = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, lpName); 12 } 13 if (m_hMemory == NULL) 14 { 15 ostringstream os; 16 os << "CreateFileMapping: %s Failed!" << lpName << endl; 17 LOGFMTE(os.rdbuf()->str().c_str()); 18 } 19 m_pMemFlag = (SM_MEMFLAG*)::MapViewOfFile(m_hMemory, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(SM_MEMFLAG)); 20 m_DataBuff = m_pMemFlag->m_DataBuff; 21 m_DataHead = &m_pMemFlag->m_DataHead; 22 { 23 TCHAR tcTempName[96] = _T(""); 24 _stprintf_s(tcTempName, _T("%s.Mutex"), lpName); 25 m_hMutex = ::CreateMutex(NULL, FALSE, tcTempName); 26 if (m_hMutex == NULL) 27 { 28 LOGFMTE(_T("CreateMutex %s Failed"), tcTempName); 29 } 30 _stprintf_s(tcTempName, _T("%s.Event"), lpName); 31 m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, tcTempName); 32 if (m_hEvent == NULL) 33 { 34 LOGFMTE(_T("CreateEvent %s Failed"), tcTempName); 35 } 36 } 37 } 38 CShareMem::~CShareMem(void) 39 { 40 ::UnmapViewOfFile(m_pMemFlag); 41 ::CloseHandle(m_hMemory); 42 ::CloseHandle(m_hMutex); 43 ::CloseHandle(m_hEvent); 44 } 45 #define SM_LOCK ::WaitForSingleObject(m_hMutex, INFINITE) 46 #define SM_UNLOCK ::ReleaseMutex(m_hMutex) 47 #define SM_SIGNAR ::SetEvent(m_hEvent) 48 #define SM_RESETEVEN ::ResetEvent(m_hEvent) 49 CShareMem::SM_MEMPTR::SM_MEMPTR(CShareMem& ShareMemory, SM_MEMFLAG* pMemFlag, SM_MEMFLAG::eMemFlag eFlag) 50 :m_ShareMemory(ShareMemory) 51 ,m_pMemFlag(pMemFlag) 52 { 53 ::WaitForSingleObject(m_ShareMemory.m_hMutex, INFINITE); 54 m_pMemFlag->dwProcessId = m_ShareMemory.m_dwProcessId; 55 m_pMemFlag->eLastAction = eFlag; 56 } 57 58 CShareMem::SM_MEMPTR::~SM_MEMPTR() 59 { 60 ::ReleaseMutex(m_ShareMemory.m_hMutex); 61 ::SetEvent(m_ShareMemory.m_hEvent); 62 } 63 CShareMem::EM_EVENS CShareMem::WaitEvent(DWORD dwTimeOut) 64 { 65 DWORD dwState = WaitForSingleObject(m_hEvent, dwTimeOut); 66 EM_EVENS rtEvent = EV_NONE; 67 SM_LOCK; 68 switch (dwState) 69 { 70 case WAIT_OBJECT_0: 71 switch (m_pMemFlag->eLastAction) 72 { 73 case SM_MEMFLAG::ACT_READ: 74 rtEvent = m_pMemFlag->dwProcessId == m_dwProcessId ? EV_READ_THIS : EV_READ_OTHER; 75 break; 76 case SM_MEMFLAG::ACT_WRITE: 77 rtEvent = m_pMemFlag->dwProcessId == m_dwProcessId ? EV_WRITE_THIS : EV_WRITE_OTHER; 78 break; 79 } 80 break; 81 case WAIT_TIMEOUT: 82 rtEvent = EV_TIMEOUT; 83 break; 84 default: 85 break; 86 } 87 SM_UNLOCK; 88 SM_RESETEVEN; 89 return rtEvent; 90 } 91 92 void CShareMem::WaitEvent(EM_EVENS eEvent) 93 { 94 while (WaitEvent(INFINITE) != eEvent); 95 } 96 bool CShareMem::Write(UDPFrameData* pDataHead, const char* pData, eDATATYPE type) 97 { 98 for (;;) 99 { 100 if (m_pMemFlag == NULL) 101 { 102 return false; 103 } 104 if (m_pMemFlag->eLastAction == SM_MEMFLAG::ACT_WRITE) 105 { 106 Sleep(1); 107 } 108 else 109 { 110 break; 111 } 112 } 113 114 SM_LOCK; 115 memcpy_s(m_DataHead, HEADER_SIZE, pDataHead, HEADER_SIZE); 116 memcpy_s(m_DataBuff, pDataHead->m_nFrameSize, pData, pDataHead->m_nFrameSize); 117 m_pMemFlag->eDataType = type; 118 m_pMemFlag->dwProcessId = m_dwProcessId; 119 m_pMemFlag->eLastAction = SM_MEMFLAG::ACT_WRITE; 120 SM_SIGNAR; 121 SM_UNLOCK; 122 return true; 123 } 124 bool CShareMem::Read(UDPFrameData* pDataHead, char* pData, eDATATYPE* type) 125 { 126 for(;;) 127 { 128 if (m_pMemFlag == NULL) 129 { 130 return false; 131 } 132 if (m_pMemFlag->eLastAction != SM_MEMFLAG::ACT_WRITE)// 133 { 134 Sleep(1); 135 } 136 else 137 { 138 break; 139 } 140 } 141 SM_LOCK; 142 memcpy_s(pDataHead, HEADER_SIZE, m_DataHead, HEADER_SIZE); 143 memcpy_s(pData, pDataHead->m_nFrameSize, m_DataBuff, pDataHead->m_nFrameSize); 144 if (type) 145 { 146 *type = m_pMemFlag->eDataType; 147 } 148 m_pMemFlag->dwProcessId = m_dwProcessId; 149 m_pMemFlag->eLastAction = SM_MEMFLAG::ACT_READ; 150 SM_SIGNAR; 151 SM_UNLOCK; 152 return true; 153 }