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號