WINCE內(nèi)存映射技術(shù)_第1頁
WINCE內(nèi)存映射技術(shù)_第2頁
免費預(yù)覽已結(jié)束,剩余2頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、2008 年 08 月 06 日 星期三 15:121. 用途和基本操作用于不同進程之間的內(nèi)存共享操作 , 可以將一個物理文件映射到內(nèi)存當(dāng) 中然后直接利用分配到的或者打開的命名共享內(nèi)存的地址空間實現(xiàn)資源共享訪 問2. 相關(guān)流程1) 新建命名共享內(nèi)存首先利用 CreateFile 或者 CreateFileForMapping 獲得一個用于映射的 物理文件句柄 , 然后利用該文件句柄結(jié)合 CreateFileMapping 得到一個命名的 共享內(nèi)存映射文件句柄2) 打開命名共享內(nèi)存如果需要共享已經(jīng)存在的命名共享內(nèi)存映射文件 , 使用 OpenFileMapping 函數(shù)3) 獲得地址空間指針進行

2、內(nèi)存映射文件的讀寫和一般的文件讀寫不同 , 是直接面對你申請的 地址空間,為此需要使用 MapViewOfFile 得到相關(guān)的地址 LPVOID 類型的指針.如果需要進行文件寫入 , 可以通過類型轉(zhuǎn)換直接對于內(nèi)存地址進行賦 值, 比如 :memcpy( lpAddress, lpBuf, .)這里自然需要防止內(nèi)存溢出的情況如果是讀取操作 , 呵呵將參數(shù)順序調(diào)整一下就可以了4) 將內(nèi)存復(fù)制到所映射的物理文件上面FlushM apViewOfFile 函數(shù)可以將內(nèi)存里面的內(nèi)容 DUM 到物理磁盤上面5) 卸載內(nèi)存映射文件地址指針UnmapViewOffFile 函數(shù)就是卸載6) 關(guān)閉內(nèi)存映射文件太

3、簡單了 , CloseHandle 搞定2. 相關(guān)背景其實內(nèi)存映射技術(shù)本身沒有什么難度 , 關(guān)鍵在于共享內(nèi)存映射的使用上 面, 特別是進行不同進程之間的同步 , 尤其是如果該內(nèi)存映射是跨機器的情況 下, 你需要考慮不同的異常情況 .詳解 ( 付林林 ) 與虛擬內(nèi)存一樣,內(nèi)存映射文件用來保留一個地址空間,并提交物理存儲 器。早期的內(nèi)存映射文件并不是提交物理內(nèi)存供調(diào)用者使用,而是提交永久存儲器上的文件數(shù)據(jù)。當(dāng)然操作系統(tǒng)會為永久存儲器保留一個讀緩沖區(qū),這樣讀 取文件數(shù)據(jù)就快多了。內(nèi)存映射文件的特點使它很適合于加載EXE 或 DLL 文件。這樣可以節(jié)省內(nèi)存又減少了加載所需時間。還可以使用它來映射大容量

4、的 文件,這樣就不必在讀取文件數(shù)據(jù)前設(shè)置很大的緩沖區(qū)。另外內(nèi)存映射文件常 用于進程間通信,也是進程間通信的主要手段,其它進程之間通信機制都是基 于內(nèi)存映射文件來實現(xiàn)。為了更快的在進程之間通信,現(xiàn)在的內(nèi)存映射文件也 可以提交物理內(nèi)存,這樣內(nèi)存映射文件既可以提交物理內(nèi)存又可以提交文件。Win dows CE.NET 同樣支持無名和有名的內(nèi)存映射文件。我建議在開發(fā)軟件的過程中,如果需要讀寫大容量的文件,或者需要在不同進程內(nèi)的線程之間通 信,最好采用內(nèi)存映射文件,而且最好在全局地址空間內(nèi)(0 x4200 0000 到0 x7FFF FFFF)分配。這會使我們事半功倍。1 映射數(shù)據(jù)文件第一步:調(diào)用 Cr

5、eateFileForMapping 函數(shù)。在 Windows CE.NET 中推薦使 用這個函數(shù)替代 CreateFile 函數(shù)。 CreateFileForMapping 函數(shù)由內(nèi)核執(zhí)行并 創(chuàng)建文件,它也可以打開由 CreateFile 函數(shù)創(chuàng)建的文件。其參數(shù)同 CreateFile 相似。參數(shù) 1 指定文件路徑,注意文件路徑的格式是沒有盤符的, 參數(shù) 2 指定訪問方式(讀或?qū)懀瑓?shù) 3 指定共享模式,參數(shù) 4 指定安全屬性 (必須設(shè)置為 NULL,參數(shù) 5 指定是創(chuàng)建還是打開文件,參數(shù) 6 指定文件屬 性,參數(shù) 7 忽略。具體參數(shù)細節(jié)參見 WindowsCE.NET 幫助。函數(shù)返回創(chuàng)建

6、或者 打開的文件的句柄。第二步:調(diào)用 CreateFileMapping 函數(shù)。這個函數(shù)創(chuàng)建一個無名的或者有 名的內(nèi)存映射文件對象。參數(shù) 1 為文件句柄。這個值由 CreateFileForMapping 函數(shù)返回。參數(shù) 2 為安全屬性(必須設(shè)置為 NULL,參數(shù) 3 指定要映射的文件 的保護屬性(只讀或者讀寫),參數(shù) 4 和參數(shù) 5 共同用于指定要映射的文件的 大小。文件的容量過大將導(dǎo)致 32 位整數(shù)也不能表示,所以這里用 64 位變量表 示,其中參數(shù) 4 為高 32 位數(shù),參數(shù) 5 為低 32 位數(shù)。最后一個參數(shù)指定內(nèi)存映 射文件的名稱。這里可以設(shè)置為NULL 表示不需要名字。第三步:調(diào)用

7、 MapViewOfFile 函數(shù)。這個函數(shù)用于保留一段足夠的地址空 間,并且將永久存儲器上的文件數(shù)據(jù)映射到這個地址空間。映射后這段地址空 間又叫做文件視圖,映射范圍可以是全部文件,也可以是部分文件。這里需要 注意的是如果文件很大,那這個函數(shù)將在全局地址空間內(nèi)分配地址空間。參數(shù) 1 指定內(nèi)存映射文件對象的句柄,這個值由 CreateFileMapping 函數(shù)返回。參 數(shù) 2 和 CreateFileMapping 函數(shù)中參數(shù) 3 很相似,都是用于限定訪問權(quán)限。參 數(shù) 3 和參數(shù) 4 共同用于指定映射區(qū)域的開始位置。其中參數(shù)3 為高 32 位數(shù),參數(shù) 4 為低 32 位數(shù)。參數(shù) 5 指定映射區(qū)

8、域的大小。需要注意的是參數(shù) 3 和參數(shù) 4 指定的 64 位數(shù)開始位置可以不是 64KB 的倍數(shù)。而其它 Windows 操作系統(tǒng)就必 須限制以 64KB 為單位。另外還要注意的是幫助文檔中說不能保證一個文件的映 射視圖是連續(xù)的,并建議為了防止訪問非法,應(yīng)該加入結(jié)構(gòu)化異常處理機制。 這個可能性我認為很小,一般對于大于 2MB 的虛擬地址空間的申請,內(nèi)核都會 在全局地址空間中分配。全局地址空間( 0 x4200 0000 到 0 x7FFF FFFF)近 1GB 的空間應(yīng)該足夠用了。畢竟Win dows CE 下的文件都很小。不過在代碼中加入結(jié) 構(gòu)化異常處理也不是壞事。我們應(yīng)該養(yǎng)成凡是讀寫文件數(shù)

9、據(jù)時都加入結(jié)構(gòu)化異 常處理的習(xí)慣。第四步:進行讀 / 寫操作。 MapViewOfFile 函數(shù)如果成功執(zhí)行,那么返回映 射視圖的首地址。這時就可以把視圖當(dāng)成是一個緩沖區(qū),開始讀或?qū)懖僮髁?。第五步:?zhí)行結(jié)束工作。先調(diào)用 UnmapViewOfFile 函數(shù)撤銷文件映射視 圖。參數(shù)只有一個,指定視圖首地址。然后調(diào)用 CloseHandle 函數(shù)關(guān)閉內(nèi)存映 射文件對象,參數(shù)為句柄。最后再次調(diào)用 CloseHandle 函數(shù),關(guān)閉打開的文件 的句柄。2 進程之間通信進程之間有時需要通信。系統(tǒng)提供的進程之間的通信機制比如COM 剪貼板等,在底層實現(xiàn)上都是利用內(nèi)存映射文件技術(shù)。其實進程之間通信的思路很

10、簡單,在這里我順便講一下。在其它 Win dows 操作系統(tǒng)中,每個進程獨自占有 4GB 的地址空間,高 2GB 是內(nèi)核的地址空間,而低 2GB 是進程的地址空間。一 個進程所能訪問的所有低 2GB 地址都是自己的地址空間,當(dāng)訪問內(nèi)核地址空間 時就會受到內(nèi)核的限制。這樣一個進程當(dāng)然無法訪問其它進程了。為解決進程 間通信的問題,內(nèi)存映射文件技術(shù)被利用作為解決方案。原來內(nèi)存映射文件只 映射類似磁盤一類的存儲器上的文件。而為了更快速地在進程之間通信,內(nèi)存 映射文件還可以提交物理內(nèi)存。實現(xiàn)方法是通過訪問同一個內(nèi)存映射文件對象 (映射到物理內(nèi)存),兩個進程或多個進程就能夠訪問到同一塊物理內(nèi)存,這 樣一個

11、進程寫到物理內(nèi)存的數(shù)據(jù),其它進程就能夠看到了。而Win dows CE 雖然每個進程只占有 32MB 的地址空間,而且所有進程全部處于 4GB 的地址空間中, 但是彼此還是不能夠隨意訪問的。在 Win dows CE 下除了使用內(nèi)存映射文件技術(shù) 外,還有一種方法也很適合使用,就是利用對象存儲。對象存儲本身使用 RAM 文件系統(tǒng),用普通的操作文件的 API 就可以創(chuàng)建、 讀取存在于對象存儲區(qū)域內(nèi) 的文件。Windows目錄就存在于對象存儲區(qū)域內(nèi)。我們可以利用在 Windows 目錄下創(chuàng)建文件來實現(xiàn)進程間通信。這種方法既實現(xiàn)簡單,只需調(diào)用幾個文件 API 函數(shù),又可以減少通信時間,因為Window

12、s 目錄存在于物理內(nèi)存中,數(shù)據(jù) I/O 當(dāng)然很快了。利用對象存儲來實現(xiàn)進程之間的通信是我自己想出來的, MSD 或其它文檔并沒有這方面的說明。需要注意的就是對象存儲區(qū)域的大小。 另外從實現(xiàn)的代碼量上看也不如內(nèi)存映射文件技術(shù)。下面講解如何利用內(nèi)存映射文件實現(xiàn)進程之間的通信。假設(shè)進程A 和進程B 需要通信,那么進程 A 需要先創(chuàng)建一個內(nèi)存映射文件(之前不必調(diào)用CreateFileForMapping 函數(shù)來創(chuàng)建文件,因為不需要創(chuàng)建文件)。這個內(nèi)存映 射文件可以是在永久存儲器中,也可以是在內(nèi)存中。為了減小通信時間,最好 提交物理內(nèi)存。進程 A 在調(diào)用 CreateFileMapping 函數(shù)時,參數(shù) 1 指定為 INVALID_HANDLE_VALU這表示這個內(nèi)存映射文件對象將要把物理內(nèi)存提交到 地址空間中。最后一個參數(shù)一定要指定一個名字。進程B 也同樣調(diào)用CreateFileMapping 函數(shù),而且參數(shù)相同。內(nèi)核會根據(jù)名字來判斷是否已經(jīng)存 在一個內(nèi)存映射文件對象,如果創(chuàng)建了就返回原來的對象的句柄。接下去就不 用細說了。參照 5.1 去執(zhí)行就可以了。要注意的是進程 B 調(diào)用 CreateFileMapping 函數(shù)后要按如下代碼檢驗函數(shù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論