Qt程序访问C++创建的共享内存失败题解
1、Qt使用QSharedMemory的setKey方法创建内存,共享内存名称不兼容
---Qt的setKey()与C++的CreateFileMapping()命名规则差异
Qt的QSharedMemory在创建时会自动生成一个native key(如 qipc_sharedmemory_ 前缀),而直接使用setKey()设置的名称无法与C++的API直接匹配。
C++创建一个MySharedMemory的共享内存如下,其创建出的共享内存名称为"MySharedMemory":
HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // 使用物理内存而非文件 NULL, // 默认安全属性 PAGE_READWRITE, // 可读可写 0, // 内存大小高位 sizeof(SharedData), // 内存大小低位 L"MySharedMemory" // 共享内存名称(需唯一) );
Qt使用setKey创建一个MySharedMemory的共享内存如下,其创建出的共享内存名称为"qipc_sharedmemory_MySharedMemory35...",无法与C++创建的共享内存名称匹配,所以附加失败:
QSharedMemory sharedMem; sharedMem.setKey("MySharedMemory"); QString strKey = sharedMem.nativeKey(); if (!sharedMem.attach(QSharedMemory::ReadOnly)) { qCritical() << u8"附加共享内存失败:" << sharedMem.errorString(); return -1; }

2、Qt使用QSharedMemory的setNativeKey方法创建内存,共享内存名称兼容
Qt中使用setNativeKey后,Qt的lock()与unlock()将失效,需要自行实现同步机制
Qt使用setNativeKey创建一个MySharedMemory的共享内存如下,其创建出的共享内存名称为"MySharedMemory",与C++创建的共享内存名称兼容,附加成功:
QSharedMemory sharedMem; sharedMem.setNativeKey("MySharedMemory"); QString strKey = sharedMem.nativeKey(); if (!sharedMem.attach(QSharedMemory::ReadOnly)) { qCritical() << u8"附加共享内存失败:" << sharedMem.errorString(); return -1; }

3、Qt访问C++共享内存的完整实例
#include <QCoreApplication> #include <QSharedMemory> #include <QSystemSemaphore> #include <QDebug> #include <QThread> // 必须与 C++ 端的结构体完全一致 #pragma pack(push, 1) struct SharedData { int count; char buffer[256]; }; #pragma pack(pop) int main(int argc, char *argv[]) { QCoreApplication a(argc, argv);
qDebug()<<sizeof (SharedData); // 1. 附加到共享内存(名称必须包含 Global\\) QSharedMemory sharedMem; sharedMem.setNativeKey("MySharedMemory"); QString strKey = sharedMem.nativeKey(); if (!sharedMem.attach(QSharedMemory::ReadOnly)) { qCritical() << u8"附加共享内存失败:" << sharedMem.errorString(); return -1; } // 2. 创建/打开信号量(模拟 Windows 互斥体) QSystemSemaphore semaphore("MyMutex", 1, QSystemSemaphore::Open); strKey = semaphore.key(); while (true) { semaphore.acquire(); // 加锁(阻塞直到可用) // 3. 直接读取内存数据 sharedMem.lock(); SharedData* data = static_cast<SharedData*>(sharedMem.data()); if (data) { qDebug() << "ID:" << data->count << "Message:" << data->buffer; } else { qWarning() << "内存指针无效"; } sharedMem.unlock(); semaphore.release(); // 解锁 QThread::msleep(100); } sharedMem.detach(); return 1; }
记性太差,需要这么记下来

浙公网安备 33010602011771号