CreateFileMapping函數初探

測試創建和打開文件映射的時候老是得到"句柄無效"的錯誤, 仔細看了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/" 前綴的特殊含義就被忽略了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章