C++使用共享内存实现进程间通信

本文转自:http://soft.chinabyte.com/database/116/12615616.shtml

文件映射是一种实现进程间单向或双向通信的机制。它允许两个或多个本地进程间相互通信。为了共享文件或内存,所有的进程必须使用相同的文件映射的名字或是句柄。



  为了实现共享文件,第一个进程先调用CreateFile方法。接下来调用CreateFileMapping方法来创建一个文件映射对象。并为文件映射指明一个句柄和名称。由于事件,信号,互斥对象和文件映射等这些内核对象都共享同一个名字空间,所以如果这个名字和其他一个对象的名称重名的话那么将创建失败。


  为了实现共享内存,进程应首先调用CreateFileMapping函数然后在hFile参数中传入INVALID_HANDLE_VALUE宏来替代句柄。相应的文件映射对象会从系统的分页文件中获得一段内存。如果hFile参数的值是INVALID_HANDLE_VALUE,那么你在调用CreateFileMapping时必须给共享内存指定一个大小值。


  使用共享内存或文件的进程必须使用MapViewOfFile函数或MapViewOfFileEx函数来创建一个文件视图。


  下面我们创建一个名称为"Local\SampleMap"的文件映射对象,并将一个字符串写入到文件映射中。


  我们将创建两个程序,一个是服务程序,一个是客户程序。服务程序负责创建文件映射。


  服务程序命名为CppFileMappingServer,它的执行过程是


  1、创建一个特定大小的文件映射对象,名称为“Local\SampleMap”


  2、将这个对象的文件视图映射到进程的地址空间,然后向视图中写入字符串。

Server完整源码:

#pragma region Includes

  #include "stdafx.h"

  #include <aclapi.h>

  #pragma endregion

  #define MAP_PREFIX L"Local\\"

  #define MAP_NAME L"SampleMap"

  #define FULL_MAP_NAME MAP_PREFIX MAP_NAME

  // Max size of the file mapping object.

  #define MAP_SIZE 65536

  // File offset where the view is to begin.

  #define VIEW_OFFSET 0

  // The number of bytes of a file mapping to map to the view. All bytes of the

  // view must be within the maximum size of the file mapping object (MAP_SIZE).

  // If VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to

  // the end of the file mapping.

  #define VIEW_SIZE 1024

  // Unicode string message to be written to the mapped view. Its size in byte

  // must be less than the view size (VIEW_SIZE).

  #define MESSAGE L"Message from the first process."

  int wmain(int argc, wchar_t* argv[])

  {

  HANDLE hMapFile = NULL;

  PVOID pView = NULL;

  // Create the file mapping object.

  hMapFile = CreateFileMapping(

  INVALID_HANDLE_VALUE, // Use paging file - shared memory

  NULL, // Default security attributes

  PAGE_READWRITE, // Allow read and write access

  0, // High-order DWORD of file mapping max size

  MAP_SIZE, // Low-order DWORD of file mapping max size

  FULL_MAP_NAME // Name of the file mapping object

  );

  if (hMapFile == NULL)

  {

  wprintf(L"CreateFileMapping failed w/err 0x%08lx\n", GetLastError());

  goto Cleanup;

  }

  wprintf(L"The file mapping (%s) is created\n", FULL_MAP_NAME);

  // Map a view of the file mapping into the address space of the current

  // process.

  pView = MapViewOfFile(

  hMapFile, // Handle of the map object

  FILE_MAP_ALL_ACCESS, // Read and write access

  0, // High-order DWORD of the file offset

  VIEW_OFFSET, // Low-order DWORD of the file offset

  VIEW_SIZE // The number of bytes to map to view

  );

  if (pView == NULL)

  {

  wprintf(L"MapViewOfFile failed w/err 0x%08lx\n", GetLastError());

  goto Cleanup;

  }

  wprintf(L"The file view is mapped\n");

  // Prepare a message to be written to the view.

  PWSTR pszMessage = MESSAGE;

  DWORD cbMessage = (wcslen(pszMessage) + 1) * sizeof(*pszMessage);

  // Write the message to the view.

  memcpy_s(pView, VIEW_SIZE, pszMessage, cbMessage);

  wprintf(L"This message is written to the view:\n\"%s\"\n",

  pszMessage);

  // Wait to clean up resources and stop the process.

  wprintf(L"Press ENTER to clean up resources and quit");

  getchar();

  Cleanup:

  if (hMapFile)

  {

  if (pView)

  {

  // Unmap the file view.

  UnmapViewOfFile(pView);

  pView = NULL;

  }

  // Close the file mapping object.

  CloseHandle(hMapFile);

  hMapFile = NULL;

  }

  return 0;

  }


Client完整源码

#pragma region Includes

  #include "stdafx.h"

  #include <aclapi.h>

  #pragma endregion

  #define MAP_PREFIX L"Local\\"

  #define MAP_NAME L"SampleMap"

  #define FULL_MAP_NAME MAP_PREFIX MAP_NAME

  // File offset where the view is to begin.

  #define VIEW_OFFSET 0

  // The number of bytes of a file mapping to map to the view. All bytes of the

  // view must be within the maximum size of the file mapping object. If

  // VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to the

  // end of the file mapping.

  #define VIEW_SIZE 1024

  int wmain(int argc, wchar_t* argv[])

  {

  HANDLE hMapFile = NULL;

  PVOID pView = NULL;

  // Try to open the named file mapping identified by the map name.

  hMapFile = OpenFileMapping(

  FILE_MAP_READ, // Read access

  FALSE, // Do not inherit the name

  FULL_MAP_NAME // File mapping name

  );

  if (hMapFile == NULL)

  {

  wprintf(L"OpenFileMapping failed w/err 0x%08lx\n", GetLastError());

  goto Cleanup;

  }

  wprintf(L"The file mapping (%s) is opened\n", FULL_MAP_NAME);

  // Map a view of the file mapping into the address space of the current

  // process.

  pView = MapViewOfFile(

  hMapFile, // Handle of the map object

  FILE_MAP_READ, // Read access

  0, // High-order DWORD of the file offset

  VIEW_OFFSET, // Low-order DWORD of the file offset

  VIEW_SIZE // The number of bytes to map to view

  );

  if (pView == NULL)

  {

  wprintf(L"MapViewOfFile failed w/err 0x%08lx\n", GetLastError());

  goto Cleanup;

  }

  wprintf(L"The file view is mapped\n");

  // Read and display the content in view.

  wprintf(L"Read from the file mapping:\n\"%s\"\n", (PWSTR)pView);

  // Wait to clean up resources and stop the process.

  wprintf(L"Press ENTER to clean up resources and quit");

  getchar();

  Cleanup:

  if (hMapFile)

  {

  if (pView)

  {

  // Unmap the file view.

  UnmapViewOfFile(pView);

  pView = NULL;

  }

  // Close the file mapping object.

  CloseHandle(hMapFile);

  hMapFile = NULL;

  }

  return 0;

  }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值