I'm trying to learn how to use QSharedMemory
with a simple application. This application should
It is able to create the memory and write to it over + over without issue. However, it is not able to read from it. It has to attach to it first in order to read from the shared memory, and it errors out when it tries to attach.
The error it return is that it already exists:
QSharedMemory::AlreadyExists
The QSharedMemory
constructor that's being used sets the key name, which is good, because that one has access to .attach()
. So using sharedMemory.setKey()
wouldn't fix it (and I tried anyway to be sure). I'm not using the other constructor specified that only takes in a parent.
I tried calling .detach()
but that just makes the memory unable to be found later.
I tried .setNativeKey()
but that did not fix the issue. Also, both nativeKeys and regular keys when printed inside writeData()
and readData()
show the exact same string.
I've looked at these posts + consulted the official QSharedMemory
documentation but am unable to figure out the issue:
#include <QApplication>
#include <QSharedMemory>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QImage>
#include <QBuffer>
#include <QDataStream>
#include <QDebug>
class SharedMemoryDialog : public QDialog
{
Q_OBJECT
public:
SharedMemoryDialog(QWidget *parent = nullptr)
: QDialog(parent)
, shmKey("ShmemKey")
, sharedMemory(shmKey, 0)
{
setupUI();
}
private slots:
void writeData()
{
// Create sample data
QString data = "\nHello from shared memory!";
// Create a buffer and stream
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QDataStream out(&buffer);
out << data;
// Create shared memory segment
int size = buffer.size();
if (!sharedMemory.create(size)) {
qDebug() << "Size:" << sharedMemory.size();
if (sharedMemory.error() == QSharedMemory::AlreadyExists) {
sharedMemory.attach();
} else {
qDebug() << "Unable to create shared memory segment:"
<< sharedMemory.errorString();
return;
}
}
// Debugging
qDebug() << "Key:" << sharedMemory.key();
qDebug() << "Native Key:" << sharedMemory.nativeKey();
// Copy data to shared memory
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), size));
sharedMemory.unlock();
// // detach + see if it still exists
// if (sharedMemory.detach()) {
// qDebug() << "successfully detached.";
// }
// // Check if segment still exists
// if (sharedMemory.isAttached()) {
// qDebug() << "still attached.";
// sharedMemory.detach();
// qDebug() << "now detached.";
// }
qDebug() << "Data written to shared memory";
}
void readData()
{
qDebug() << "\nGONNA READ DATA NOW";
qDebug() << "Key:" << sharedMemory.key();
qDebug() << "Native Key:" << sharedMemory.nativeKey();
// Errors out here :(
if (!sharedMemory.attach()) {
switch (sharedMemory.error()) {
case QSharedMemory::NotFound:
qDebug() << "Shared memory not found";
break;
case QSharedMemory::PermissionDenied:
qDebug() << "Permission denied";
break;
case QSharedMemory::InvalidSize:
qDebug() << "Invalid size";
break;
case QSharedMemory::AlreadyExists:
qDebug() << "Already exists";
break;
default:
qDebug() << "Unknown error:" << sharedMemory.errorString();
}
return;
}
qDebug() << "here";
// Read data from shared memory
sharedMemory.lock();
QBuffer buffer;
buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
buffer.open(QBuffer::ReadOnly);
QDataStream in(&buffer);
QString data;
in >> data;
sharedMemory.unlock();
sharedMemory.detach();
qDebug() << "Data read from shared memory:" << data;
}
private:
void setupUI()
{
QVBoxLayout *layout = new QVBoxLayout(this);
QPushButton *writeButton = new QPushButton("Write to Shared Memory");
QPushButton *readButton = new QPushButton("Read from Shared Memory");
layout->addWidget(writeButton);
layout->addWidget(readButton);
connect(writeButton, &QPushButton::clicked, this, &SharedMemoryDialog::writeData);
connect(readButton, &QPushButton::clicked, this, &SharedMemoryDialog::readData);
setWindowTitle("Shared Memory Example");
}
QString shmKey;
QSharedMemory sharedMemory;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SharedMemoryDialog dialog;
dialog.show();
return app.exec();
}
#include "main.moc"
I was able to read the string you expect :
Data read from shared memory: "\nHello from shared memory!"
However I think you need to rework your business logic with something like that:
`
// Errors out here :(
if (!sharedMemory.isAttached() && !sharedMemory.attach()) {
switch (sharedMemory.error()) {
case QSharedMemory::NotFound:
qDebug() << "Shared memory not found";
break;
You have to check if the shared memory is attached first and then attach it and detach or, whatever you desire but I think that call to attach every time ruins your application. Try checking with that example check first.