应用场景:
比如 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
#include
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
#include
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
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
#include
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
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
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}