QSharedMemory是qt提供对共享内存操作的类,主要用来对内存卡写数据和读数据。
常用api:
1、void QSharedMemory::setKey(const QString &key)
为共享内存设置键值。如何当前的内存共享对象已经链接到底层的共享内存段(isAttached),则在设置新的键值前分离开(detach)。
2、bool QSharedMemory::create(int size, QSharedMemory::AccessMode mode = ReadWrite)
该函数根据共享内存的Key值来创建一个size大小的共享内存段,可以根据mode设为ReadWrite可读可写或者ReadOnly只读模式。
3、bool QSharedMemory::attach(QSharedMemory::AccessModemode= ReadWrite)该函数将会依据共享内存对象的Key值,来将共享内存对象与实际的共享内存逻辑地址相链接,这样进程就可以通过QSharedMemory对象来访问实际的共享内存了。 4、bool QSharedMemory::detach() 将进程与共享内存段分离。如果这是链接到共享内存段的最后一个进程,那么这个共享内存段将被系统释放,也就是说,共享内存中的内容将被销毁。
5、bool QSharedMemory::lock() 这是一个可以锁住共享内存段以供该进程访问的信号量。当进程对共享内存进程操作时,为防止其它进程也对该内存进行改动从而操作数据不同步的情况,需要将内存进行锁定,也就是lock。 6、bool QSharedMemory::unlock() 当对共享内存操作完成后,需要释放共享内存段上的锁。否则其它进程无法对共享内存进行任何操作。 发送端代码:
void QtWidgetsSendData::writeSharedMemory(QImage img)
{
if (mSharedMemSender == nullptr)
{
mSharedMemSender = new QSharedMemory();
// 设置共享内存区域Key
mSharedMemSender->setKey("PicShared");
if (mSharedMemSender->isAttached())
{
mSharedMemSender->detach();
}
// 获取需要共享的数据大小
int r = mSharedMemSender->size();
// 创建共享内存区域
auto hh = mSharedMemSender->create(588810);
}
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
// 创建QDataStream对象并指定数据存储对象为buffer
QDataStream inStream(&buffer);
// 将图片数据传入
inStream << img;
// 将共享内存区域锁定
mSharedMemSender->lock();
//写入数据
memcpy((char*)mSharedMemSender->data(), (char*)buffer.data().data(), buffer.size());
// 将共享内存区域解锁
mSharedMemSender->unlock();
}
接受端代码:
void QtWidgetsReceiveData::readSharedMemory()
{
QSharedMemory sharedMemReceiver;
// 设置共享内存区域Key
sharedMemReceiver.setKey("PicShared");
// 将共享内存区域与程序挂接
int rr = sharedMemReceiver.isAttached();
int r = sharedMemReceiver.attach();
auto test = sharedMemReceiver.errorString();
//qDebug() << "创建共享内存失败: " << sharedMemReceiver.errorString();
// 将共享内存区域锁定
sharedMemReceiver.lock();
// 获取共享内存大小(此处相当于数据大小)
int size = sharedMemReceiver.size();
QBuffer buffer;
// 将共享内存的数据设置到buffer容器中
buffer.setData((char*)sharedMemReceiver.constData(), size);
// 然后以只读的方式打开
buffer.open(QBuffer::ReadOnly);
// 创建QDataStream对象读取数据,并指定数据buffer
QDataStream outStream(&buffer);
// 创建QImage并通过数据流对象将图片数据写入
QImage img;
outStream >> img;
// 将共享内存解锁
sharedMemReceiver.unlock();
// 将挂接的共享内存与程序分离
sharedMemReceiver.detach();
ui.label_srcImage->setPixmap(QPixmap::fromImage(img));
}