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; }
posted @ 2025-03-14 16:20  左边的翼  阅读(209)  评论(0)    收藏  举报