window API一天一练之共享内存

今天学习win下共享内存的进程通信,仿照Qt的共享内存类,封装了一个简单的类。虽然比不上Qt的类那么完善和强大,但是通过学习也达到了理解win共享内存的方式。

class WinSharedMemory { public: WinSharedMemory(string szkey = ""); ~WinSharedMemory(); bool CreateSize(int size); void *Data(); const void *ConstData() const; bool Attach(); bool Detach(); bool IsAttach(); bool Lock(); bool UnLock(); intSize(); void Setkey(string szKey); string Key(); string GetErrorMessage(); protected: void cleanHandle(); private: stringm_errorMessage; intm_size; stringm_memKey; boolm_isLock; HANDLEm_mutex; HANDLEm_fileMapping; void*m_pMemory; };

WinSharedMemory::WinSharedMemory( string szkey /*= ""*/ ):m_memKey(szkey) ,m_isLock(false),m_mutex(NULL),m_pMemory(NULL),m_size(0),m_fileMapping(NULL) { }WinSharedMemory::~WinSharedMemory() { this->Setkey(""); }bool WinSharedMemory::CreateSize( int size ) { if (m_memKey == "") { m_errorMessage = "没有设置共享内存名"; return false; } if (size < 1) { m_errorMessage = "设置内存大小必须大于0"; return false; } m_size = size; m_fileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,m_size,m_memKey.c_str()); if (m_fileMapping == NULL) { m_errorMessage ="创建共享内存失败"; return false; } if (GetLastError() == ERROR_ALREADY_EXISTS) { m_errorMessage ="共享内存已存在"; return false; } return true; }void * WinSharedMemory::Data() { return m_pMemory; }const void * WinSharedMemory::ConstData() const { return m_pMemory; }bool WinSharedMemory::Attach() { if (m_fileMapping) { m_pMemory = (void *)MapViewOfFile(m_fileMapping,FILE_MAP_ALL_ACCESS,0,0,0); if (m_pMemory == NULL) { m_errorMessage = "映射内存失败"; return false; } } return true; }bool WinSharedMemory::Lock() { if (!m_isLock) { string szMutexkey = m_memKey + "_mutex"; m_mutex = CreateMutex(NULL,false,szMutexkey.c_str()); WaitForSingleObject(m_mutex,INFINITE); m_isLock = true; } else { m_errorMessage = "内存已被锁定"; return false; } }bool WinSharedMemory::IsAttach() { return(m_pMemory != NULL); ; }bool WinSharedMemory::UnLock() { if (m_isLock) { ReleaseMutex(m_mutex); m_isLock = false; } return true; }int WinSharedMemory::Size() { return m_size; }void WinSharedMemory::Setkey( string szKey ) { m_memKey = szKey; }string WinSharedMemory::Key() { return m_memKey; }string WinSharedMemory::GetErrorMessage() { return m_errorMessage; }bool WinSharedMemory::Detach() { if (!UnmapViewOfFile(m_pMemory)) { m_errorMessage = "释放共享内存失败"; return false; } m_size = 0; m_pMemory = NULL; cleanHandle(); return true; }void WinSharedMemory::cleanHandle() { if (m_fileMapping) { CloseHandle(m_fileMapping); m_fileMapping = NULL; } if (m_mutex) { CloseHandle(m_mutex); m_mutex = NULL; } }




Qt的测速程序代码:
SharedMemory::SharedMemory(QWidget *parent, Qt::WFlags flags) : QDialog(parent, flags) { m_pWriteDataBtn = new QPushButton(tr("WriteData"),this); m_pReadDataBtn = new QPushButton(tr("ReadData"),this); m_pTextEdit = new QTextEdit(this); connect(m_pReadDataBtn,SIGNAL(clicked()),this,SLOT(ReadDataFromMemorySlot())); connect(m_pWriteDataBtn,SIGNAL(clicked()),this,SLOT(WriteDataToMemorySlot())); //ui.setupUi(this); }SharedMemory::~SharedMemory() {}void SharedMemory::ReadDataFromMemorySlot() { int size = 1024 * 1024 ; WinSharedMemory sharedMemory; sharedMemory.Setkey("FileMapObject"); if (sharedMemory.IsAttach()) { sharedMemory.Detach(); } sharedMemory.CreateSize(size); sharedMemory.Attach(); sharedMemory.Lock(); char *pmemory = (char*)sharedMemory.Data(); char *pText = new char[size]; strcpy(pText,pmemory); sharedMemory.UnLock(); sharedMemory.Detach(); m_pTextEdit->setText(QString::fromStdString(pText)); }void SharedMemory::WriteDataToMemorySlot() { int size = 1024 * 1024 ; WinSharedMemory sharedMemory; sharedMemory.Setkey("FileMapObject"); if (sharedMemory.IsAttach()) { sharedMemory.Detach(); } sharedMemory.CreateSize(size); sharedMemory.Attach(); sharedMemory.Lock(); char *pmemory = (char*)sharedMemory.Data(); string text = m_pTextEdit->toPlainText().toStdString(); strcpy(pmemory,text.c_str()); sharedMemory.UnLock(); }void SharedMemory::resizeEvent( QResizeEvent *event ) { this->setFixedSize(QSize(500,300)); m_pReadDataBtn->setGeometry(0,0,100,20); m_pReadDataBtn->setGeometry(120,0,100,20); m_pTextEdit->setGeometry(0,25,500,270); }


window API一天一练之共享内存
文章图片

【window API一天一练之共享内存】
左边的程序进行写入数据,右边读取。经过验证,可以进行通信。


    推荐阅读