在Win32中,每个进程有自己的地址空间,一个进程不能轻易地访问另一个进程地址空间中的数据,所以不能像16位Windows那样做。Win32系统允许多个进程(运行在同一计算机上)使用内存映射文件来共享数据。实际上,其他共享和传送数据的技术,诸如使用SendMessage或者PostMessage,都在内部使用了内存映射文件。
  
这种数据共享是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。但要注意,对文件映射对象要使用同一名字。
  
以下是一段使用内存映射文件的代码:
  
创建:
  
HANDLE  s_hFileMap  =  CreateFileMapping((HANDLE)0XFFFFFFFF,NULL,PAGE_READWRITE,  0,  4*1024,_TEXT("MyCustShareData"));
(此函数寻找一个名字为"MyCustShareData"的内存映射文件,不存在则创建,存在则返回已有的句柄,所以当返回值不为空的话,还须检查GetLastError,如果得到ERROR_ALREADY_EXISTS,则表明该名字的内存映射文件已经存在,并未创建成功)
  
读写:HANDLE  hFile  =  OpenFileMapping(FILE_MAP_READ  |  FILE_MAP_WRITE,  FALSE,  _TEXT("MyCustShareData"));//最后一个参数为名字,必须与创建的相同
  
if(hFile  !=  NULL)
{
        LPVOID  lpView  =    MapViewOfFile(hFile,  FILE_MAP_READ  |  FILE_MAP_WRITE,  0,  0,  0);//将内存映射文件的一个视图映射到当前的地址空间
        if  ((int  *)lpView  !=  NULL)  
        {
  int  sheardata  =  (int*)lpview;   //读   
                  (int  *)lpview  =  88;   //写
        }
        UpmapViewOfFile((LPVOID)  lpview);
}
CloseHandle(hFile);其中MapViewOfFile的原型如下所示:
LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // 映射文件对象的句柄
  DWORD dwDesiredAccess,       // 访问模式
  DWORD dwFileOffsetHigh,      // 位移的高位
  DWORD dwFileOffsetLow,       // 位移的低位(与前一个参数一起构成64位的位移量)
  SIZE_T dwNumberOfBytesToMap  // 映射量(单位为Byte,当设为0时表示映射整个文件)
);您所提到的mapviewoffileEx函数的原型如下所示:
LPVOID MapViewOfFileEx(
  HANDLE hFileMappingObject,   
  DWORD dwDesiredAccess,       
  DWORD dwFileOffsetHigh,      
  DWORD dwFileOffsetLow,       
  SIZE_T dwNumberOfBytesToMap, 
  LPVOID lpBaseAddress         
);其中前五个参数的含义同上,第六个参数给出一个调用映射文件的进程的地址,要求文件映射从该地址开始。这个值必须是一个系统内存分配的最小粒度的整数倍,否则此函数调用失败。要获得内存分配的粒度,可以调用GetSystemInfo函数。如果指定的内存地址没有足够的空间,则函数也失败。如果此参数的值设为NULL,则操作系统选择从何地址开始进行文件映射,这样,函数的功能与MapViewOfFile相同。  
关于内存映射文件的进一步的信息,您可以参看:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/filemap_61d3.asp和
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/filemap_2it4.asp等有关信息。
  
-  微软全球技术中心  VC技术支持
  
本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款
(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
  
为了为您创建更好的讨论环境,请参加我们的用户满意度调查
(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。

解决方案 »

  1.   

    在Win32中,每个进程有自己的地址空间,一个进程不能轻易地访问另一个进程地址空间中的数据,所以不能像16位Windows那样做。Win32系统允许多个进程(运行在同一计算机上)使用内存映射文件来共享数据。实际上,其他共享和传送数据的技术,诸如使用SendMessage或者PostMessage,都在内部使用了内存映射文件。
      
    这种数据共享是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。但要注意,对文件映射对象要使用同一名字。
      
    以下是一段使用内存映射文件的代码:
      
    创建:
      
    HANDLE  s_hFileMap  =  CreateFileMapping((HANDLE)0XFFFFFFFF,NULL,PAGE_READWRITE,  0,  4*1024,_TEXT("MyCustShareData"));
    (此函数寻找一个名字为"MyCustShareData"的内存映射文件,不存在则创建,存在则返回已有的句柄,所以当返回值不为空的话,还须检查GetLastError,如果得到ERROR_ALREADY_EXISTS,则表明该名字的内存映射文件已经存在,并未创建成功)
      
    读写:HANDLE  hFile  =  OpenFileMapping(FILE_MAP_READ  |  FILE_MAP_WRITE,  FALSE,  _TEXT("MyCustShareData"));//最后一个参数为名字,必须与创建的相同
      
    if(hFile  !=  NULL)
    {
            LPVOID  lpView  =    MapViewOfFile(hFile,  FILE_MAP_READ  |  FILE_MAP_WRITE,  0,  0,  0);//将内存映射文件的一个视图映射到当前的地址空间
            if  ((int  *)lpView  !=  NULL)  
            {
      int  sheardata  =  (int*)lpview;   //读   
                      (int  *)lpview  =  88;   //写
            }
            UpmapViewOfFile((LPVOID)  lpview);
    }
    CloseHandle(hFile);其中MapViewOfFile的原型如下所示:
    LPVOID MapViewOfFile(
      HANDLE hFileMappingObject,   // 映射文件对象的句柄
      DWORD dwDesiredAccess,       // 访问模式
      DWORD dwFileOffsetHigh,      // 位移的高位
      DWORD dwFileOffsetLow,       // 位移的低位(与前一个参数一起构成64位的位移量)
      SIZE_T dwNumberOfBytesToMap  // 映射量(单位为Byte,当设为0时表示映射整个文件)
    );您所提到的mapviewoffileEx函数的原型如下所示:
    LPVOID MapViewOfFileEx(
      HANDLE hFileMappingObject,   
      DWORD dwDesiredAccess,       
      DWORD dwFileOffsetHigh,      
      DWORD dwFileOffsetLow,       
      SIZE_T dwNumberOfBytesToMap, 
      LPVOID lpBaseAddress         
    );其中前五个参数的含义同上,第六个参数给出一个调用映射文件的进程的地址,要求文件映射从该地址开始。这个值必须是一个系统内存分配的最小粒度的整数倍,否则此函数调用失败。要获得内存分配的粒度,可以调用GetSystemInfo函数。如果指定的内存地址没有足够的空间,则函数也失败。如果此参数的值设为NULL,则操作系统选择从何地址开始进行文件映射,这样,函数的功能与MapViewOfFile相同。  
    关于内存映射文件的进一步的信息,您可以参看:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/filemap_61d3.asp和
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/filemap_2it4.asp等有关信息。
      
    -  微软全球技术中心  VC技术支持
      
    本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
      
    为了为您创建更好的讨论环境,请参加我们的用户满意度调查
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
      

  2.   

    拷个例子:
    fileQRS=CreateFile(gstr,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);lowSize=GetFileSize(fileQRS,&highSize);RecNum=lowSize/sizeof(QRSDATA);fpQRS=CreateFileMapping(fileQRS,NULL,PAGE_READWRITE,highSize,lowSize,NULL);mapQRS=(QRSDATA *)MapViewOfFile(fpQRS,FILE_MAP_WRITE,0,0,0);if(mapQRS!=NULL)
    for(i=0;i<RecNum;i++)
    {
    qrsRR+=mapQRS[i].R_R;
    qrsW+=mapQRS[i].Width;
    qrsH+=mapQRS[i].Height;
    qrsA+=mapQRS[i].Area;
    //mapQRS[i].Flag=1;
    }UnmapViewOfFile(mapQRS);
    CloseHandle(fpQRS);
    CloseHandle(fileQRS);