Qt进程间通信 之使用QSharedMemory

来源:互联网 发布:java难学吗 编辑:程序博客网 时间:2024/05/29 13:54
应用场景:
比如 QQ 与 QQ 音乐、QQ 影音等共享用户头像。

使用QSharedMemory入门,看这篇基本就够了。
https://www.devbean.net/2013/11/qt-study-road-2-ipc/

摘要:
0、 QSharedMemory是Qt 提供的一种各个平台均有支持的进程间交互的方式。
1、Qt 使用QSharedMemory类操作共享内存段。我们可以把QSharedMemory看做一种指针,这种指针指向分配出来的一个共享内存段。而这个共享内存段是由底层的操作系统提供,可以供多个线程或进程使用。因此,QSharedMemory可以看做是专供 Qt 程序访问这个共享内存段的指针。
2、进程间通信(Inter-Process Communication,IPC) 离不开平台特性。有关共享内存段,各个平台的实现也有所不同:
  • Windows:QSharedMemory不“拥有”共享内存段。当使用了共享内存段的所有线程或进程中的某一个销毁了QSharedMemory实例,或者所有的都退出,Windows 内核会自动释放共享内存段。
  • Unix:QSharedMemory“拥有”共享内存段。当最后一个线程或进程同共享内存分离,并且调用了QSharedMemory的析构函数之后,Unix 内核会将共享内存段释放。注意,这里与 Windows 不同之处在于,如果使用了共享内存段的线程或进程没有调用QSharedMemory的析构函数,程序将会崩溃。
3、初始化QSharedMemory对象时,指定一个字符串名称,两个进程就是用这个字符串识别共享内存的。

这篇的例子是在一个进程里,我来一个在两个进程里实现的。
先在app1里输入fff,点击send。
在app2里点击read,TextLabel会变成fff
代码见最后。win7、qt creator、qt 5.6.2。要用designer自己画一下ui。

Qt官方文档的例子:
http://doc.qt.io/qt-5/qtcore-ipc-sharedmemory-example.html

使用Dll文件实现进程间通信:
http://blog.csdn.net/mickeyty/article/details/51721860
用#pragma data_seg()在DLL中定义一个共享的,有名字的数据段。

app1的代码:
dialog.h
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QSharedMemory>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();


private slots:
void on_pushButton_clicked();

private:
Ui::Dialog *ui;
QSharedMemory sharedMemory;
};

#endif // DIALOG_H

dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QBuffer>
#include<QDebug>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog),
sharedMemory("QSharedMemoryExample")
{
ui->setupUi(this);
}

Dialog::~Dialog()
{
delete ui;
}

void Dialog::on_pushButton_clicked()
{
if (sharedMemory.isAttached())
qDebug()<<"aaa";

QString content = ui->lineEdit->text();

// load into shared memory
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QDataStream out(&buffer);
out << content;
int size = buffer.size();

if (!sharedMemory.create(size)) {
qDebug()<<"Unable to create shared memory segment.";
return;
}
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), size));
sharedMemory.unlock();

}
main.cpp
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();

return a.exec();
}
下面是app2的代码
dialog.h
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QSharedMemory>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();

private slots:
void on_pushButton_clicked();

private:
Ui::Dialog *ui;
QSharedMemory sharedMemory;
};

#endif // DIALOG_H

dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include<QBuffer>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog),
sharedMemory("QSharedMemoryExample")
{
ui->setupUi(this);
}

Dialog::~Dialog()
{
delete ui;
}

void Dialog::on_pushButton_clicked()
{
if (!sharedMemory.attach()) {
ui->label->setText(tr("Unable to attach to shared memory segment.\n" \
"Load an image first."));
return;
}

QBuffer buffer;
QDataStream in(&buffer);

QString cc;

sharedMemory.lock();
buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
buffer.open(QBuffer::ReadOnly);
in >> cc;
sharedMemory.unlock();

sharedMemory.detach();
ui->label->setText(cc);



}
main.cpp
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();

return a.exec();
}



原创粉丝点击