Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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;
    }
    
    

  • Lifetime Qt Champion

    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.



  • @SGaist Thank you! I'm fix it. But it's doesn't fix a problem. I'm already testing both variants. In my post it is only typo.


  • Lifetime Qt Champion

    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.



  • I'm already try to run two copies of Qt application. And it can't transfet data from one thread to another.


  • Lifetime Qt Champion

    What exact error are you getting ?



  • @SGaist I'm changed value of key to simple ASCII: "example".
    Not effect (((
    May be you have an example? I searching it in Google but only one example in qt.io was found.
    No any other(((



  • Probably off topic, but did you consider using QLocalSocket and WINAPI Named Pipe instead



  • @VRonin Good idea. It's will be my fallback. I need to high speed data transfer (up to 10 MBit/s) and shared memory is a faster method of IPC. It's most suitable for my application.



  • 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


  • Lifetime Qt Champion

    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.


  • Qt Champions 2019

    @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?



  • @VRonin Thank you for recommendation. I will try to use named pipe in my application. It's also good solution for my application.



  • @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.


  • Qt Champions 2019

    @MR.Smith @SGaist pointed out what you should try



  • I got successfully transfer data via named pipes. It's good solution and I will use it, not shared memory.
    Thank you every one for your help and recommendations.


Log in to reply