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

http://blog.csdn.net/hzqhbc/article/details/24409077

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完整源码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #pragma region Includes  
  2.   
  3.   #include "stdafx.h"  
  4.   
  5.   #include <aclapi.h>  
  6.   
  7.   #pragma endregion  
  8.   
  9.   #define MAP_PREFIX L"Local\\"  
  10.   
  11.   #define MAP_NAME L"SampleMap"  
  12.   
  13.   #define FULL_MAP_NAME MAP_PREFIX MAP_NAME  
  14.   
  15.   // Max size of the file mapping object.  
  16.   
  17.   #define MAP_SIZE 65536  
  18.   
  19.   // File offset where the view is to begin.  
  20.   
  21.   #define VIEW_OFFSET 0  
  22.   
  23.   // The number of bytes of a file mapping to map to the view. All bytes of the  
  24.   
  25.   // view must be within the maximum size of the file mapping object (MAP_SIZE).  
  26.   
  27.   // If VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to  
  28.   
  29.   // the end of the file mapping.  
  30.   
  31.   #define VIEW_SIZE 1024  
  32.   
  33.   // Unicode string message to be written to the mapped view. Its size in byte  
  34.   
  35.   // must be less than the view size (VIEW_SIZE).  
  36.   
  37.   #define MESSAGE L"Message from the first process."  
  38.   
  39.   int wmain(int argc, wchar_t* argv[])  
  40.   
  41.   {  
  42.   
  43.   HANDLE hMapFile = NULL;  
  44.   
  45.   PVOID pView = NULL;  
  46.   
  47.   // Create the file mapping object.  
  48.   
  49.   hMapFile = CreateFileMapping(  
  50.   
  51.   INVALID_HANDLE_VALUE, // Use paging file - shared memory  
  52.   
  53.   NULL, // Default security attributes  
  54.   
  55.   PAGE_READWRITE, // Allow read and write access  
  56.   
  57.   0, // High-order DWORD of file mapping max size  
  58.   
  59.   MAP_SIZE, // Low-order DWORD of file mapping max size  
  60.   
  61.   FULL_MAP_NAME // Name of the file mapping object  
  62.   
  63.   );  
  64.   
  65.   if (hMapFile == NULL)  
  66.   
  67.   {  
  68.   
  69.   wprintf(L"CreateFileMapping failed w/err 0x%08lx\n", GetLastError());  
  70.   
  71.   goto Cleanup;  
  72.   
  73.   }  
  74.   
  75.   wprintf(L"The file mapping (%s) is created\n", FULL_MAP_NAME);  
  76.   
  77.   // Map a view of the file mapping into the address space of the current  
  78.   
  79.   // process.  
  80.   
  81.   pView = MapViewOfFile(  
  82.   
  83.   hMapFile, // Handle of the map object  
  84.   
  85.   FILE_MAP_ALL_ACCESS, // Read and write access  
  86.   
  87.   0, // High-order DWORD of the file offset  
  88.   
  89.   VIEW_OFFSET, // Low-order DWORD of the file offset  
  90.   
  91.   VIEW_SIZE // The number of bytes to map to view  
  92.   
  93.   );  
  94.   
  95.   if (pView == NULL)  
  96.   
  97.   {  
  98.   
  99.   wprintf(L"MapViewOfFile failed w/err 0x%08lx\n", GetLastError());  
  100.   
  101.   goto Cleanup;  
  102.   
  103.   }  
  104.   
  105.   wprintf(L"The file view is mapped\n");  
  106.   
  107.   // Prepare a message to be written to the view.  
  108.   
  109.   PWSTR pszMessage = MESSAGE;  
  110.   
  111.   DWORD cbMessage = (wcslen(pszMessage) + 1) * sizeof(*pszMessage);  
  112.   
  113.   // Write the message to the view.  
  114.   
  115.   memcpy_s(pView, VIEW_SIZE, pszMessage, cbMessage);  
  116.   
  117.   wprintf(L"This message is written to the view:\n\"%s\"\n",  
  118.   
  119.   pszMessage);  
  120.   
  121.   // Wait to clean up resources and stop the process.  
  122.   
  123.   wprintf(L"Press ENTER to clean up resources and quit");  
  124.   
  125.   getchar();  
  126.   
  127.   Cleanup:  
  128.   
  129.   if (hMapFile)  
  130.   
  131.   {  
  132.   
  133.   if (pView)  
  134.   
  135.   {  
  136.   
  137.   // Unmap the file view.  
  138.   
  139.   UnmapViewOfFile(pView);  
  140.   
  141.   pView = NULL;  
  142.   
  143.   }  
  144.   
  145.   // Close the file mapping object.  
  146.   
  147.   CloseHandle(hMapFile);  
  148.   
  149.   hMapFile = NULL;  
  150.   
  151.   }  
  152.   
  153.   return 0;  
  154.   
  155.   }  


Client完整源码

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #pragma region Includes  
  2.   
  3.   #include "stdafx.h"  
  4.   
  5.   #include <aclapi.h>  
  6.   
  7.   #pragma endregion  
  8.   
  9.   #define MAP_PREFIX L"Local\\"  
  10.   
  11.   #define MAP_NAME L"SampleMap"  
  12.   
  13.   #define FULL_MAP_NAME MAP_PREFIX MAP_NAME  
  14.   
  15.   // File offset where the view is to begin.  
  16.   
  17.   #define VIEW_OFFSET 0  
  18.   
  19.   // The number of bytes of a file mapping to map to the view. All bytes of the  
  20.   
  21.   // view must be within the maximum size of the file mapping object. If  
  22.   
  23.   // VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to the  
  24.   
  25.   // end of the file mapping.  
  26.   
  27.   #define VIEW_SIZE 1024  
  28.   
  29.   int wmain(int argc, wchar_t* argv[])  
  30.   
  31.   {  
  32.   
  33.   HANDLE hMapFile = NULL;  
  34.   
  35.   PVOID pView = NULL;  
  36.   
  37.   // Try to open the named file mapping identified by the map name.  
  38.   
  39.   hMapFile = OpenFileMapping(  
  40.   
  41.   FILE_MAP_READ, // Read access  
  42.   
  43.   FALSE, // Do not inherit the name  
  44.   
  45.   FULL_MAP_NAME // File mapping name  
  46.   
  47.   );  
  48.   
  49.   if (hMapFile == NULL)  
  50.   
  51.   {  
  52.   
  53.   wprintf(L"OpenFileMapping failed w/err 0x%08lx\n", GetLastError());  
  54.   
  55.   goto Cleanup;  
  56.   
  57.   }  
  58.   
  59.   wprintf(L"The file mapping (%s) is opened\n", FULL_MAP_NAME);  
  60.   
  61.   // Map a view of the file mapping into the address space of the current  
  62.   
  63.   // process.  
  64.   
  65.   pView = MapViewOfFile(  
  66.   
  67.   hMapFile, // Handle of the map object  
  68.   
  69.   FILE_MAP_READ, // Read access  
  70.   
  71.   0, // High-order DWORD of the file offset  
  72.   
  73.   VIEW_OFFSET, // Low-order DWORD of the file offset  
  74.   
  75.   VIEW_SIZE // The number of bytes to map to view  
  76.   
  77.   );  
  78.   
  79.   if (pView == NULL)  
  80.   
  81.   {  
  82.   
  83.   wprintf(L"MapViewOfFile failed w/err 0x%08lx\n", GetLastError());  
  84.   
  85.   goto Cleanup;  
  86.   
  87.   }  
  88.   
  89.   wprintf(L"The file view is mapped\n");  
  90.   
  91.   // Read and display the content in view.  
  92.   
  93.   wprintf(L"Read from the file mapping:\n\"%s\"\n", (PWSTR)pView);  
  94.   
  95.   // Wait to clean up resources and stop the process.  
  96.   
  97.   wprintf(L"Press ENTER to clean up resources and quit");  
  98.   
  99.   getchar();  
  100.   
  101.   Cleanup:  
  102.   
  103.   if (hMapFile)  
  104.   
  105.   {  
  106.   
  107.   if (pView)  
  108.   
  109.   {  
  110.   
  111.   // Unmap the file view.  
  112.   
  113.   UnmapViewOfFile(pView);  
  114.   
  115.   pView = NULL;  
  116.   
  117.   }  
  118.   
  119.   // Close the file mapping object.  
  120.   
  121.   CloseHandle(hMapFile);  
  122.   
  123.   hMapFile = NULL;  
  124.   
  125.   }  
  126.   
  127.   return 0;  
  128.   
  129.   }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值