qt为进程间通讯提供了QSharedMemory类来访问共享内存,实现进程间通讯。
使用QSharedMemory访问共享内存的发送端一般写法是首先在构造QSharedMemory时写入key,只有写入key以后才能创建、关联等对共享内存的操作。而读取端也是依靠key相连接。
需要注意的是,传递信息一般使用QByteArray类型传递,接收以后再通过fromLocal8Bit转为QString,直接使用QString传递如果带有中文会乱码。
然后在发送函数当中首先依靠isAttached判断该进程是否已关联到共享内存段,然后创建、锁定、发送、解锁。
发送端示例如下:
#pragma once
#include
#include
#include
class QSharedMemory;
class MyShareMemory : public QObject
{
Q_OBJECT
public:
explicit MyShareMemory(QObject *parent = 0);
virtual ~MyShareMemory();
QByteArray GetSharedLine();
void SetSharedLine(const QByteArray shareLine);
void TransportString(); //写入数据到共享内存
void MyDelay(int time); //延时函数
private:
QSharedMemory *m_sharedMemory;
QByteArray m_array;
};
#include "MyShareMemory.h"
#include
#include
#include
#include
#include
#include
#include
MyShareMemory::MyShareMemory(QObject *parent):
QObject(parent)
{
m_sharedMemory = new QSharedMemory("test");
SetSharedLine("E:/WZX/media_888/video/苹果平板演示.mkv");
}
MyShareMemory::~MyShareMemory()
{
}
QByteArray MyShareMemory::GetSharedLine()
{
return m_array;
}
void MyShareMemory::SetSharedLine(const QByteArray shareLine)
{
m_array = shareLine;
qDebug() << QString::fromLocal8Bit(m_array) << "-------------------------------------";
}
void MyShareMemory::TransportString()
{
if (m_sharedMemory->isAttached()) //此进程是否关联到共享内存段
{
if (!m_sharedMemory->detach()) //判断是否从共享内存段中分离进程。
{
qDebug() << "sharedMemory is not detach now.";
return;
}
}
QByteArray array = GetSharedLine();
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QDataStream out(&buffer);
out << array;
if (!m_sharedMemory->create(buffer.size()))
{
qDebug() << m_sharedMemory->errorString() << " create failed";
return;
}
m_sharedMemory->lock(); //锁定共享内存段
char* to = static_cast
const char* from = buffer.data().data();
memcpy(to, from, qMin(m_sharedMemory->size(), static_cast
//memset(to, 0, qMin(m_sharedMemory->size(), static_cast
m_sharedMemory->unlock(); //解锁
MyDelay(500); //留给AirShareUp时间读取内容
m_sharedMemory->lock(); //锁定共享内存段
memset(to, 0, qMin(m_sharedMemory->size(), static_cast
m_sharedMemory->unlock(); //解锁
}
void MyShareMemory::MyDelay(int time)
{
QElapsedTimer et;
et.start();
while (et.elapsed() < time)
{
QCoreApplication::processEvents();
}
}
接收端一般写法是首先在构造QSharedMemory时设置和发送端一样的key以便于访问到。然后在接收函数当中首先使用attach尝试将进程加入到共享内存段。然后锁定、接收、解锁、剥离进程。
接收端示例:
#ifndef MYSHAREDMEMORY_H
#define MYSHAREDMEMORY_H
#pragma once
#include
#include
#include
class MySharedMemory : public QObject
{
Q_OBJECT
public:
explicit MySharedMemory(QObject *parent = 0);
virtual ~MySharedMemory(void);
QString GetSharedLine();
void SetSharedLine(QByteArray sharedArray);
bool RecivedShared();
private:
QString m_sharedLine; //接收到的字符串
QSharedMemory *m_sharedMemory;
};
#endif
#include "MySharedMemory.h"
#include
#include
#include
MySharedMemory::MySharedMemory(QObject *parent):
QObject(parent)
{
m_sharedMemory = new QSharedMemory("test");
}
MySharedMemory::~MySharedMemory(void)
{
}
QString MySharedMemory::GetSharedLine()
{
return m_sharedLine;
}
void MySharedMemory::SetSharedLine(QByteArray sharedArray)
{
m_sharedLine = QString::fromLocal8Bit(sharedArray);
}
bool MySharedMemory::RecivedShared()
{
if(!m_sharedMemory->attach()) //进程加入到共享内存段失败
{
//qDebug() << "Can not attach...";
SetSharedLine("No Data");
return false;
}
QBuffer buffer;
QDataStream in(&buffer);
QByteArray array;
m_sharedMemory->lock(); //锁定
//接收数据
buffer.setData((char*)m_sharedMemory->constData(), m_sharedMemory->size());
buffer.open(QBuffer::ReadOnly);
in >> array;
m_sharedMemory->unlock(); //解锁
m_sharedMemory->detach(); //剥离
SetSharedLine(array);
return true;
}