Send data between processes via QSharedMemory
-
Hello,
I'm need to communicate with another process in OS.
First process I would like to write on Qt (5.6.1). Second process on Visual Studio 2013 on WinAPI. I think that QSharedMemory is a good way for this.I used Shared Memory Example. It's correctly work in single process.
Already I used Creating Named Shared Memory example from MSDN. It's also correctly work.
But I can't transfer data from Qt application to WinAPI application. Qt application is correctly write data and I can read it in Qt application, but in WinAPI application is not possible to connect to shared memory and read it. Error: Could not open file mapping object.
May be there is more detailed example for QSharedMemory?
What is a problem here?My source code is bellow.
Creating shared memory:Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog), sharedMemory("Global\\SharedMemoryExample") { ui->setupUi(this); }
For write data to shared memory:
void Dialog::on_writeButton_clicked() { QString data = ui->bufferLineEdit->text(); if(sharedMemory.isAttached()) sharedMemory.detach(); QBuffer buffer; buffer.open(QBuffer::ReadWrite); QDataStream out(&buffer); out << data; int size = buffer.size(); if(!sharedMemory.create(size)) { ui->bufferLineEdit->setText("ERROR: Shared Memory not created"); return; } sharedMemory.lock(); char *to = (char*)sharedMemory.data(); const char *from = buffer.data().data(); memcpy(to, from, qMin(sharedMemory.size(), size)); sharedMemory.unlock(); }
For read shared memory:
void Dialog::on_readButton_clicked() { ui->bufferLineEdit->clear(); if (!sharedMemory.isAttached()) { ui->bufferLineEdit->setText("ERROR: Shared Memory not attached"); return; } QBuffer buffer; QDataStream in(&buffer); QString data; data.clear(); sharedMemory.lock(); buffer.setData((char*)sharedMemory.constData(), sharedMemory.size()); buffer.open(QBuffer::ReadOnly); in >> data; sharedMemory.unlock(); sharedMemory.detach(); ui->bufferLineEdit->setText(data); }
And second WinApi application:
#include <windows.h> #include <stdio.h> #include <conio.h> #include <tchar.h> #pragma comment(lib, "user32.lib") #define BUF_SIZE 256 TCHAR szName[]=TEXT("Global//SharedMemoryExample"); int _tmain() { HANDLE hMapFile; LPCTSTR pBuf; hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, // read/write access FALSE, // do not inherit the name szName); // name of mapping object if (hMapFile == NULL) { _tprintf(TEXT("Could not open file mapping object (%d).\n"), GetLastError()); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); CloseHandle(hMapFile); return 1; } MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; }
-
Hi and welcome to devnet,
Did you see that you are not using the same key for both applications ?
For the Qt application you are using backslashes and for the WinAPI application your are using forward slashes.
-
Hi and welcome to devnet,
Did you see that you are not using the same key for both applications ?
For the Qt application you are using backslashes and for the WinAPI application your are using forward slashes.
-
I don't remember if there's a limitation in the characters you can use as key, but i'd start with only ASCII stuff without any special signs.
-
What exact error are you getting ?
-
I don't remember if there's a limitation in the characters you can use as key, but i'd start with only ASCII stuff without any special signs.
-
Probably off topic, but did you consider using QLocalSocket and WINAPI Named Pipe instead
-
Probably off topic, but did you consider using QLocalSocket and WINAPI Named Pipe instead
-
Disclaimer
what follows is just speculation, not advice.
The problem with shared memory, as I understand it, is that is no way to signal the reader application that new data is available to consume.
10 MBit/s is not a lot, named pipe should be able to manage it without a problem, in fact, a TCP socket connected to localhost should also be able to handle that transfer rate without a sweat. Both their typical transfer rates are in the multiple Gbit/sec
-
Check the detailed documentation of QSharedMemory and the setNativeKey. They explain how to achieve communication with non Qt application.
-
@SGaist When I run two copies of Ot application and write some data to shared memory from one of them and the next trying read data from another I have problem: sharedMemory.isAttached() == FALSE for shared memory with same keys.
-
Disclaimer
what follows is just speculation, not advice.
The problem with shared memory, as I understand it, is that is no way to signal the reader application that new data is available to consume.
10 MBit/s is not a lot, named pipe should be able to manage it without a problem, in fact, a TCP socket connected to localhost should also be able to handle that transfer rate without a sweat. Both their typical transfer rates are in the multiple Gbit/sec
-
@MR.Smith Didn't you say before that it is working when using two Qt apps and doesn't work if one app is not a Qt app?
-
@jsulm Yes, it's true. I can transfer data from one Qt application to another copy of this Qt application, but I can't transfer data from Qt application to WinAPI application.