天天看點

CreateFileMapping的MSDN翻譯和使用心得

測試建立和打開檔案映射的時候老是得到"句柄無效"的錯誤, 仔細看了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/" 字首的特殊含義就被忽略了