zoukankan      html  css  js  c++  java
  • 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

     

    进程间通信的方式有很多种,其底层原理使用的都是内存映射文件。

    本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信。

     

    进程1

    按钮【Create  mapping of Data】用来创建命名内存映射文件,后备存储器为页交换文件,而非磁盘上的文件,大小为4K,将全部大小映射到进程地址空间,将Data中的数据写入该内存映射文件,然后撤销对文件视图的映射。注意在进程1里不能CloseHandle(m_hFileMapping)

     

    进程2

    按钮【Open maping and get Data】用来打开进程1创建的命名内存映射文件,将全部大小映射到进程地址空间,从中读出数据,将数据内容放到Data里。 

    按钮【Close mapping of Data】用来关闭CloseHandle进程1返回的内存映射文件m_hFileMapping。

     1 void CMemoryMappingDlg::OnBnClickedBtnCreate2()
     2 {
     3     // TODO: 在此添加控件通知处理程序代码;
     4     LPCTSTR lpFileMappingName = _T("MMFSharedData");
     5     m_hFileMapping = CreateFileMapping(
     6         INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4 * 1024, lpFileMappingName);
     7     DWORD dwErr = GetLastError();
     8 
     9     if (NULL == m_hFileMapping )
    10     {  
    11         AfxMessageBox(_T("无法创建该内存映射文件")); 
    12         return; 
    13     }
    14     if (dwErr == ERROR_ALREADY_EXISTS)
    15     {
    16         AfxMessageBox(_T("存在同名内存映射文件"));
    17         CloseHandle(m_hFileMapping);
    18         return;
    19     }
    20 
    21     PVOID pMapOfView = MapViewOfFile(m_hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 /*4 * 1024*/);
    22     if (NULL == pMapOfView)
    23     {
    24         AfxMessageBox(_T("映射该文件错误")); 
    25         CloseHandle(m_hFileMapping);
    26         return;
    27     }
    28 
    29     ZeroMemory(pMapOfView, 4 * 1024);
    30 
    31     CString strText;
    32     GetDlgItemText(IDC_EDIT_DATA, strText);
    33     memcpy_s(pMapOfView, (strText.GetLength() + 1) * sizeof(TCHAR), strText.GetBuffer(), 
    34         (strText.GetLength() + 1) * sizeof(TCHAR));
    35 
    36     UnmapViewOfFile(pMapOfView);
    37     //CloseHandle(m_hFileMapping);  不能执行此句,否则进程2不能打开该命名内存映射文件。
    38 }
    39 
    40 void CMemoryMappingDlg::OnBnClickedBtnClose()
    41 {
    42     // TODO: 在此添加控件通知处理程序代码;
    43     CloseHandle(m_hFileMapping);    
    44 }
    45 
    46 void CMemoryMappingDlg::OnBnClickedBtnOpen()
    47 {
    48     // TODO: 在此添加控件通知处理程序代码
    49     LPCTSTR lpFileMappingName = _T("MMFSharedData"); 
    50 
    51     //OpenFileMapping的第一个参数一定不能是PAGE_**, 区别于CreateFileMapping函数
    52     //HANDLE hFileMapping = OpenFileMapping(PAGE_READWRITE, FALSE, lpFileMappingName);
    53     HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileMappingName);
    54 
    55     if (NULL == hFileMapping)
    56     {
    57         AfxMessageBox(_T("打不开该内存映射文件"));
    58         return;
    59     }
    60 
    61     PVOID pMapOfFile = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 /*4 * 1024 */);
    62     if (NULL == pMapOfFile)
    63     {
    64         AfxMessageBox(_T("映射该文件错误"));
    65         CloseHandle(hFileMapping);
    66         return;
    67     }
    68 
    69     TCHAR tchArr[256];
    70     ZeroMemory(tchArr, sizeof(tchArr));
    71     memcpy_s(tchArr, sizeof(tchArr), pMapOfFile, sizeof(tchArr));
    72     SetDlgItemText(IDC_EDIT_DATA, tchArr);
    73 
    74     UnmapViewOfFile(pMapOfFile);
    75     CloseHandle(hFileMapping);
    76 }

     需要注意的地方是:

    0、后备存储器为页交换文件的内存映射文件,CreateFileMapping的文件句柄参数为INVALID_HANDLE_VALUE

    1、进程1创建了命名内存映射文件后,一定不能CloseHandle(内存映射文件句柄),否则进程2不能OpenFileMapping打开该命名内存映射文件

    2、OpenFileMapping的第一个参数一定不能是PAGE_**, 区别于CreateFileMapping函数

  • 相关阅读:
    vue doubleclick 鼠标双击事件
    我是如何通过CSRF拿到Shell的
    js生成一个不重复的ID的函数的进化之路
    浅谈企业内部安全漏洞的运营(一):规范化
    如何让微信丢骰子永远只出“666”
    全能无线渗透测试工具,一个LAZY就搞定了
    关于8月31日维基解密被攻击的观察与分析
    VS2013 单元测试(使用VS2013自带的单元测试)
    解决WCF部署到IIS出现“证书必须具有能够进行密钥交换的私钥,该进程必须具有访问私钥的权限”
    VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试
  • 原文地址:https://www.cnblogs.com/cuish/p/3669842.html
Copyright © 2011-2022 走看看