demo主要完成:
共享内存进行通讯,并且两个进程均可对共享数据区中数据进行修改。共享区是一个结构体。
proA为创建共享内存,要先点击proA中连接,再点击ProB中连接去读取内存。更新按钮均是对共享的结构体进行修改,显示按钮是显示当前结构体中数据。
AB两个工程的共享内存中存放的是一个结构体,AB两个工程均可对共享的结构体数据进行修改,具体代码如下:
proA:
头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSharedMemory>
#include "usedefine.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_connect_btn_clicked();
void on_update_btn_clicked();
void on_show_btn_clicked();
private:
Ui::Widget *ui;
QSharedMemory m_pSharedMemory;//共享内存
sharedlg *m_psharedlg;//结构体数据
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//m_pSharedMemory = NULL;//共享内存
setWindowTitle("proA--first connect");
m_psharedlg = NULL;
m_pSharedMemory.setKey("LD_SHARED");
}
Widget::~Widget()
{
//再关闭程序时,释放共享内存
//如果在释放内存之后,仍然有对共享内存的操作,则会报错
m_pSharedMemory.detach();
delete ui;
}
void Widget::on_connect_btn_clicked()
{
/*
* 进程A-写
分为下面几步:
检测该进程是否连接到共享内存段,如果连接,则将该进程与共享内存段分离。
从系统足够大的内存中得到一个新的共享内存段。
锁定该共享内存段,以阻止第二个对话框进程访问,将缓冲区中的图片复制进共享内存段。
将共享内存段解锁,然后第二个对话框进程就可以访问了。
*/
if(m_pSharedMemory.isAttached())
{
//将该进程与共享内存分离
if(!m_pSharedMemory.detach())
{
qDebug() << "unable to detach from shared memory" << endl;
}
}
int nsize = sizeof(sharedlg);
qDebug() << "ok"<<nsize<< endl;
//创建共享内存段
if(!m_pSharedMemory.create(nsize))
{
qDebug() << m_pSharedMemory.errorString() << "create error" <<endl;
return;
}
m_pSharedMemory.lock();
//char *pch = (char *)m_pSharedMemory.data();
//memcpy(pch, &m_psharedlg,qMin(m_pSharedMemory.size(), nsize));
m_psharedlg = (sharedlg *)m_pSharedMemory.data();
//memcpy(pch, from,sizeof(sendbuf));
m_pSharedMemory.unlock();
m_psharedlg->aa = 1;
m_psharedlg->dfei =2;
m_psharedlg->fDui=3;
m_psharedlg->nFlag =4;
m_psharedlg->nnew = 5;
QMessageBox::information(this, "ok", "proa-connect-ok");
qDebug() << "ok"<<endl;
}
void Widget::on_update_btn_clicked()
{
if(m_psharedlg == NULL)
{
return ;
}
static int ncl = 10;
m_psharedlg->aa = ncl++;
m_psharedlg->nFlag = ncl++;
m_psharedlg->dfei = ncl++;
QMessageBox::information(this,"zi",QString("ar%1,%2,%3,%4,%5").arg(m_psharedlg->aa).arg(m_psharedlg->dfei).arg(m_psharedlg->fDui).arg(m_psharedlg->nFlag).arg(m_psharedlg->nnew));
}
void Widget::on_show_btn_clicked()
{
if(m_psharedlg == NULL)
{
return ;
}
QMessageBox::information(this,"proA",QString("ar%1,%2,%3,%4,%5").arg(m_psharedlg->aa).arg(m_psharedlg->dfei).arg(m_psharedlg->fDui).arg(m_psharedlg->nFlag).arg(m_psharedlg->nnew));
}
proB
头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSharedMemory>
#include "usedefine.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_show_btn_clicked();
void on_connect_brn_clicked();
void on_update_btn_clicked();
private:
Ui::Widget *ui;
QSharedMemory m_pSharedMemory;//共享内存对象
sharedlg *m_psharedlg;//结构体
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("proB--read");
m_psharedlg = NULL;
m_pSharedMemory.setKey("LD_SHARED");
}
Widget::~Widget()
{
//再关闭程序时,释放共享内存
//如果在释放内存之后,仍然有对共享内存的操作,则会报错
m_pSharedMemory.detach();
delete ui;
}
//连接
void Widget::on_connect_brn_clicked()
{
//共享内存与该进程绑定
if(!m_pSharedMemory.attach(QSharedMemory::ReadWrite))
{
qDebug() << "unbale to attach ms" <<endl;
return;
}
// else//此段是将共享内存资源释放了,再读取数据就会有问题
// {
// //将该进程与共享内存分离
// if(!m_pSharedMemory.detach())
// {
// qDebug() << "ff unable to detach from shared memory" << endl;
// }
// qDebug() << "able to attach ms" <<endl;
// }
//从共享内存中读取数据
m_pSharedMemory.lock();
qDebug() << "size:" <<m_pSharedMemory.size()<<",,," << sizeof(sharedlg)<<endl;
m_psharedlg = NULL;
//m_psharedlg = (sharedlg *)m_pSharedMemory.constData();//ok
m_psharedlg = (sharedlg *)m_pSharedMemory.data();
//memcpy(&m_psharedlg,m_pSharedMemory.constData(),sizeof(sharedlg));/ok
m_pSharedMemory.unlock();
//m_pSharedMemory.detach();//由于后续需要处理,此处不能释放共享内存
qDebug() << "share result:" <<m_psharedlg->aa << m_psharedlg->dfei<<endl;
QMessageBox::information(this, "ok", "proB-read-ok");
}
//更新数据区中内容
void Widget::on_update_btn_clicked()
{
if(m_psharedlg == NULL)
{
return ;
}
m_psharedlg->aa = 100;
m_psharedlg->dfei =101;
QMessageBox::information(this,"proB",QString("update-ar%1,%2").arg(m_psharedlg->aa).arg(m_psharedlg->dfei));
}
//显示:显示共享数据区中内容
void Widget::on_show_btn_clicked()
{
if(m_psharedlg == NULL)
{
return ;
}
QMessageBox::information(this,"proB",QString("ar%1,%2,%3,%4,%5").arg(m_psharedlg->aa).arg(m_psharedlg->dfei).arg(m_psharedlg->fDui).arg(m_psharedlg->nFlag).arg(m_psharedlg->nnew));
}
usedefine文件
直接粘贴在两个工程中,并添加进工程
#ifndef USEDEFINE_H
#define USEDEFINE_H
struct sharedlg{
int nFlag;
float fDui;
int nnew;
double dfei;
float aa;/*
void sharedlg()
{
nFlag = -1;
fDui = -1;
nnew = -1;
dfei = -1;
aa = -1;
}*/
};
#endif // USEDEFINE_H
注意: 在析构函数处,需要对共享内存进行资源释放。 否则下次再运行时会出错
本文的有点在于:
AB两个工程均能对共享数据进行修改,而且修改的是结构体数据
代码下载地址: