CreateFileMapping()的使用心得

來源:互聯網
上載者:User

測試建立和開啟檔案對應的時候老是得到"控制代碼無效"的錯誤, 仔細看了MSDN以後才發覺是函數認識不透, 這裡把相關的解釋翻譯出來

HANDLE CreateFileMapping(
HANDLE hFile,                       //物理檔案控制代碼
LPSECURITY_ATTRIBUTES lpAttributes, //安全設定
DWORD flProtect,                    //保護設定
DWORD dwMaximumSizeHigh,            //高位檔案大小
DWORD dwMaximumSizeLow,             //低位檔案大小
LPCTSTR lpName                      //共用記憶體名稱
);

1) 物理檔案控制代碼
   任何可以獲得的物理檔案控制代碼, 如果你需要建立一個物理檔案無關的記憶體映射也無妨, 將它設定成為 0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.

   如果需要和物理檔案關聯, 要確保你的物理檔案建立的時候的訪問模式和"保護設定"匹配, 比如: 物理檔案唯讀, 記憶體映射需要讀寫就會發生錯誤. 推薦你的物理檔案使用獨佔方式建立.

   如果使用 INVALID_HANDLE_VALUE, 也需要設定需要申請的記憶體空間的大小, 無論物理檔案控制代碼參數是否有效, 這樣 CreateFileMapping 就可以建立一個和物理檔案大小無關的記憶體空間給你, 甚至超過實際檔案大小, 如果你的物理檔案有效, 而大小參數為0, 則返回給你的是一個和物理檔案大小一樣的記憶體空間位址範圍. 返回給你的檔案對應地址空間是可以通過複製, 整合或者命名得到, 初始內容為0.

2) 保護設定
   就是安全設定, 不過一般設定NULL就可以了, 使用預設的安全配置. 在win2k下如果需要進行限制, 這是針對那些將記憶體檔案對應共用給整個網路上面的應用進程使用是, 可以考慮進行限制.

3) 高位檔案大小
   弟兄們, 我想目前我們的機器都是32位的東東, 不可能得到超過32位進程所能定址的私人32位地址空間, 一般還是設定0吧, 我沒有也不想嘗試將它設定超過0的情況.
4) 低位檔案大小
   這個還是可以進行設定的, 不過為了讓其他共用使用者知道你申請的檔案對應的相關資訊, 我使用的時候是在獲得的地址空間頭部添加一個結構化描述資訊, 記錄記憶體映射的大小, 名稱等, 這樣實際申請的空間就比輸入的增加了一個頭資訊結構大小了, 我認為這樣類似BSTR的方式應該是比較合理的.

5) 共用記憶體名稱
   這個就是我今天測試的時候碰壁的禍根, 因為為了對於記憶體進行互斥訪問, 我設定了一個互斥控制代碼, 而名稱我選擇和命名共用記憶體同名, 之下就是因為他們使用共同的namespace導致了錯誤, 呵呵.

7) 調用CreateFileMapping的時候GetLastError的對應錯誤
   ERROR_FILE_INVALID     如果企圖建立一個零長度的檔案對應, 應有此報
   ERROR_INVALID_HANDLE   如果發現你的命名記憶體空間和現有的記憶體映射, 互斥量, 訊號量, 臨界區同名就麻煩了
   ERROR_ALREADY_EXISTS   表示記憶體空間命名已經存在

8) 相關服務或者平台的命名保留
   Terminal Services:
   命名可以包含 "Global" 或者 "Local" 首碼在全域或者會話名空間初級檔案對應. 其他部分可以包含任何除了()以外的字元, 可以參考 Kernel Object Name Spaces.

   Windows 2000 or later:
   如果 Terminal Services 沒有運行 "Global" 和 "Local" 首碼的特殊含義就被忽略了

              2

在開發軟體過程裡,也經常碰到進程間共用資料的需求。比如A進程建立計算資料,B進程進行顯示資料的圖形。這樣的開發方式可以把一個大程式分開成獨立的小程式,提高軟體的成功率,也可以更加適合團隊一起開發,加快軟體的開發速度。下面就來使用檔案對應的方式進行共用資料。先要使用函數CreateFileMapping來建立一個想共用的檔案資料控制代碼,然後使用MapViewOfFile來擷取共用的記憶體位址,然後使用OpenFileMapping函數在另一個進程裡開啟共用檔案的名稱,這樣就可以實現不同的進程共用資料。函數CreateFileMapping、MapViewOfFile聲明如下:WINBASEAPI__outHANDLEWINAPICreateFileMappingA(    __in     HANDLE hFile,    __in_opt LPSECURITY_ATTRIBUTES lpFileMappingAttributes,    __in     DWORD flProtect,    __in     DWORD dwMaximumSizeHigh,    __in      DWORD dwMaximumSizeLow,    __in_opt LPCSTR lpName    );WINBASEAPI__outHANDLEWINAPICreateFileMappingW(    __in     HANDLE hFile,    __in_opt LPSECURITY_ATTRIBUTES lpFileMappingAttributes,    __in     DWORD flProtect,    __in     DWORD dwMaximumSizeHigh,    __in     DWORD dwMaximumSizeLow,    __in_opt LPCWSTR lpName    );#ifdef UNICODE#define CreateFileMapping CreateFileMappingW#else#define CreateFileMapping CreateFileMappingA#endif // !UNICODEWINBASEAPI__outLPVOIDWINAPIMapViewOfFile(    __in HANDLE hFileMappingObject,    __in DWORD dwDesiredAccess,    __in DWORD dwFileOffsetHigh,    __in DWORD dwFileOffsetLow,    __in SIZE_T dwNumberOfBytesToMap    ); hFile是建立共用檔案的控制代碼。 lpFileMappingAttributes是檔案分享權限設定的屬性。 flProtect是當檔案對應時讀寫檔案的屬性。 dwMaximumSizeHigh是檔案分享權限設定的大小高位位元組。 dwMaximumSizeLow是檔案分享權限設定的大小低位位元組。 lpName是共用檔案對象名稱。 hFileMappingObject是共用檔案對象。 dwDesiredAccess是檔案分享權限設定屬性。 dwFileOffsetHigh是檔案分享權限設定區的位移地址。 dwFileOffsetLow是檔案分享權限設定區的位移地址。 dwNumberOfBytesToMap是共用資料長度。調用函數的例子如下:#001   //檔案分享權限設定。#002   //蔡軍生 2007/10/27 QQ:9073204 深圳#003   void FileMapping(void)#004   {#005         //開啟共用的檔案對象。 #006         m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, #007              FALSE,_T("TestFileMap"));#008         if (m_hMapFile)#009         {#010               //顯示共用的檔案資料。 #011              LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS, #012                   0,0,0);#013               OutputDebugString(lpMapAddr);#014         }#015         else#016         {#017               //建立共用檔案。 #018               m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL, #019                   PAGE_READWRITE,0,1024,_T("TestFileMap"));#020 #021               //拷貝資料到共用檔案裡。#022               LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,#023                    0,0,0);#024               std::wstring strTest(_T("TestFileMap"));#025               wcscpy(lpMapAddr,strTest.c_str());                 #026 #027               FlushViewOfFile(lpMapAddr,strTest.length()+1);#028         }#029   }

                          

 

             3

記憶體映射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");

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.