进程间通信:使用file-mapping kernel object(文件映射内核对象)

来源:互联网 发布:淘宝店店铺介绍范文 编辑:程序博客网 时间:2024/06/18 03:58

一:实例说明:

程序A正常运行,每隔两秒打印一次“no hello”,启动程序B后,如果按下回车,则程序A会不断打印“hello world”,程序B中再次按回车,程序A又回到原来的运行轨迹,不断打印“no hello”。

A程序:

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");

int main()
{
 HANDLE hMapFile;
 char * pBuf;

 hMapFile = CreateFileMapping(
  INVALID_HANDLE_VALUE,    // use paging file
  NULL,                    // default security
  PAGE_READWRITE,          // read/write access
  0,                       // max. object size
  BUF_SIZE,                // buffer size 
  szName);                 // name of mapping object

 if (hMapFile == NULL)
 {
  printf("Could not create file mapping object (%d).\n",
   GetLastError());
  return 1;
 }
 pBuf = (char *) MapViewOfFile(hMapFile,   // handle to map object
  FILE_MAP_ALL_ACCESS, // read/write permission
  0,                  
  0,                  
  BUF_SIZE);          

 if (pBuf == NULL)
 {
  printf("Could not map view of file (%d).\n",
   GetLastError());
  return 2;
 }

 while (1)
 {
  if (*pBuf == 'a')
  {
   printf("hello world!\n");
  }
  else
  {
   printf("no hello\n");
  }
  Sleep(2000);
 }

 UnmapViewOfFile(pBuf);

 CloseHandle(hMapFile);

 return 0;
}

 

B程序:

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");

int main()
{
 HANDLE hMapFile;
 char * pBuf;

 hMapFile = OpenFileMapping(
  FILE_MAP_ALL_ACCESS,   // read/write access
  FALSE,                 // do not inherit the name
  szName);               // name of mapping object

 if (hMapFile == NULL)
 {
  printf("Could not open file mapping object (%d).\n",
   GetLastError());
  return 1;
 }

 pBuf = (char *) MapViewOfFile(hMapFile, // handle to map object
  FILE_MAP_ALL_ACCESS,  // read/write permission
  0,                   
  0,                   
  BUF_SIZE);                  

 if (pBuf == NULL)
 {
  printf("Could not map view of file (%d).\n",
   GetLastError());
  return 2;
 }

 printf("press a key!\n");
 _getch();
 *pBuf = 'a';
 
 printf("press another key!\n");
 _getch();
 *pBuf = 'b';

 UnmapViewOfFile(pBuf);

 CloseHandle(hMapFile);

 return 0;
}

 

二,主要函数介绍:

内存映射API函数CreateFileMapping创建一个有名的共享内存:
 HANDLE CreateFileMapping(
 HANDLE hFile,                                                                 // 映射文件的句柄,
                                                                                        //设为0xFFFFFFFF以创建一个进程间共享的对象
 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,   // 安全属性
 DWORD flProtect,                                                                   // 保护方式
 DWORD dwMaximumSizeHigh,                                           //对象的大小
DWORD dwMaximumSizeLow,
LPCTSTR lpName                                                                 // 必须为映射文件命名
 );
 
与虚拟内存类似,保护方式可以是PAGE_READONLY或是PAGE_READWRITE。如果多进程都对同一共享内存进行写访问,则必须保持相互间同步。映射文件还可以指定PAGE_WRITECOPY标志,可以保证其原始数据不会遭到破坏,同时允许其他进程在必要时自由的操作数据的拷贝。
 
在创建文件映射对象后使用可以调用MapViewOfFile函数映射到本进程的地址空间内。
 
下面说明创建一个名为MySharedMem的长度为4096字节的有名映射文件:
 HANDLE hMySharedMapFile=CreateFileMapping((HANDLE)0xFFFFFFFF),
 NULL,PAGE_READWRITE,0,0x1000,"MySharedMem");
 并映射缓存区视图:
 LPSTR pszMySharedMapView=(LPSTR)MapViewOfFile(hMySharedMapFile,
 FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
 
其他进程访问共享对象,需要获得对象名并调用OpenFileMapping函数。
 HANDLE hMySharedMapFile=OpenFileMapping(FILE_MAP_WRITE,
 FALSE,"MySharedMem");
 
一旦其他进程获得映射对象的句柄,可以象创建进程那样调用MapViewOfFile函数来映射对象视图。用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的。
 
当用户进程结束使用共享内存后,调用UnmapViewOfFile函数以取消其地址空间内的视图:
       if (!UnmapViewOfFile(pszMySharedMapView))
      {
 
         AfxMessageBox("could not unmap view of file");
 
}

 

 

0 0
原创粉丝点击