今天学习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|Window XP驱动开发(十) 驱动程序的基本结构
- Android|android8.0源码下载
- window|Window XP驱动开发(八) WDK源码中 usbView 例子的编译及说明
- 《Android开发艺术探索》|Window和WindowManager--《Android开发艺术探索》阅读笔记——第八章
- web前端|JavaScript之局部变量变为全局变量
- 网络类|Windows Server 2012 R2 服务器安装与配置