使用Win32/WINAPI通过内存映射文件传输数据

sas*_*alm 8 c++ windows winapi memory-mapped-files

我需要将一些数据传输char buffer[100000];到由我启动的子进程.

现在我正在使用普通文件来执行此操作,父进程将数据写入磁盘上的文件,子进程从磁盘读取它并删除该文件.但是,这会导致不必要的磁盘写入,因此我想使用内存映射文件.

除了使用页面文件或交换文件之外,如何以不将数据写入磁盘的方式创建,写入和读取内存映射文件?

编辑:我忘了指定我想使用原始WINAPI函数,因此代码没有依赖项.我正在研究如何做到这一点,并会在准备好后自己发布答案,但如果有人有现成的代码,欢迎他们给我省点努力:)

Dav*_*nan 6

INVALID_HANDLE_VALUE调用时作为文件句柄传递CreateFileMapping:

如果hFile为INVALID_HANDLE_VALUE,则调用进程还必须在dwMaximumSizeHigh和dwMaximumSizeLow参数中指定文件映射对象的大小.在此方案中,CreateFileMapping创建指定大小的文件映射对象,该对象由系统页面文件而不是文件系统中的文件支持.

您可以使用匿名文件映射对象(将可继承句柄传递给子进程),也可以使用命名文件映射.


sas*_*alm 3

我刚刚找到了一篇关于如何执行此操作的优秀 MSDN 文章,其中包含示例代码,我将其粘贴在下面。

第一个进程(发送数据):

#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;
}
Run Code Online (Sandbox Code Playgroud)

第二个进程(接收数据):

#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;
}
Run Code Online (Sandbox Code Playgroud)