QT之共享内存

  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(m_sharedMemory->data());
    const char* from = buffer.data().data();

    memcpy(to, from, qMin(m_sharedMemory->size(), static_cast(buffer.size())));
    //memset(to, 0, qMin(m_sharedMemory->size(), static_cast(buffer.size())));

    m_sharedMemory->unlock(); //解锁

    MyDelay(500); //留给AirShareUp时间读取内容

    m_sharedMemory->lock(); //锁定共享内存段
    memset(to, 0, qMin(m_sharedMemory->size(), static_cast(buffer.size())));
    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;
}

你可能感兴趣的:(QT练手)