Search code examples
c++windowswinapimemory-mapped-files

Transferring data through a memory-mapped file using Win32/WINAPI


I need to transfer some data - char buffer[100000]; - to a child process which is started by me.

Right now I'm using an ordinary file to do so, the parent process writes the data to a file on disk, and the child process reads it from disk and deletes the file. However, that causes unnecessary writes to the disk, so I want to use memory-mapped files instead.

How do I create, write to, and then read from a memory-mapped file in such a way that no data is written to disk, except when the pagefile or swap file is used?

Edit: I forgot to specify that I want to use raw WINAPI functions, so the code doesn't have dependencies. I am researching on how to do it and will post an answer myself when ready, but if someone has ready-made code, they're welcome to save me some effort :)


Solution

  • I just found an excellent MSDN article on how to do it, complete with sample code, which I've pasted below.

    First process (sends the data):

    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <tchar.h>
    
    #define BUF_SIZE 256
    TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
    TCHAR szMsg[]=TEXT("Message from first process.");
    
    int _tmain()
    {
       HANDLE hMapFile;
       LPCTSTR pBuf;
    
       hMapFile = CreateFileMapping(
                     INVALID_HANDLE_VALUE,    // use paging file
                     NULL,                    // default security
                     PAGE_READWRITE,          // read/write access
                     0,                       // maximum object size (high-order DWORD)
                     BUF_SIZE,                // maximum object size (low-order DWORD)
                     szName);                 // name of mapping object
    
       if (hMapFile == NULL)
       {
          _tprintf(TEXT("Could not create 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;
       }
    
    
       CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
        _getch();
    
       UnmapViewOfFile(pBuf);
    
       CloseHandle(hMapFile);
    
       return 0;
    }
    

    Second process (receives the data):

    #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\\MyFileMappingObject");
    
    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;
    }