Windows 核心編程 17 記憶體對應檔

來源:互聯網
上載者:User
記憶體對應檔記憶體對應檔的3種用途:1 載入.exe 或者DLL2 用記憶體對應檔來訪問磁碟上的檔案3 處理序間通訊


1 執行程式.exe 一般載入的基地址是0X00400000,而DLL一般載入的基地址是0X10000000.
2 同一個執行程式或者DLL的多個執行個體,不會共用待用資料。
3 .exe 和DLL 使用的記憶體頁面屬性是寫時複製。

怎麼在同一個執行程式或者DLL的不同執行個體,來共用待用資料呢?比如想知道,同一個程式,運行了多個執行個體!
使用EXE檔案結構的段資訊。“Shared” 表示共用段 多個執行個體都共用
#pragma data_seg("Shared")
volatile LONG g_lApplicationInstances = 0;
#pragma data_seg()

// Tell the linker to make the Shared section readable, writable, and shared.
#pragma comment(linker, "/Section:Shared,RWS")

/******************************************************************************Module:  AppInst.cppNotices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre******************************************************************************/#include "..\CommonFiles\CmnHdr.h"     /* See Appendix A. */#include <windowsx.h>#include <tchar.h>#include "Resource.h"///////////////////////////////////////////////////////////////////////////////// The system-wide window message, unique to the applicationUINT g_uMsgAppInstCountUpdate = WM_APP+123;///////////////////////////////////////////////////////////////////////////////// Tell the compiler to put this initialized variable in its own Shared // section so it is shared by all instances of this application.#pragma data_seg("Shared")volatile LONG g_lApplicationInstances = 0;#pragma data_seg()// Tell the linker to make the Shared section readable, writable, and shared.#pragma comment(linker, "/Section:Shared,RWS")///////////////////////////////////////////////////////////////////////////////BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) {   chSETDLGICONS(hWnd, IDI_APPINST);   // Force the static control to be initialized correctly.   PostMessage(HWND_BROADCAST, g_uMsgAppInstCountUpdate, 0, 0);   return(TRUE);}///////////////////////////////////////////////////////////////////////////////void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) {   switch (id) {      case IDCANCEL:         EndDialog(hWnd, id);         break;   }}///////////////////////////////////////////////////////////////////////////////INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {   if (uMsg == g_uMsgAppInstCountUpdate) {      SetDlgItemInt(hWnd, IDC_COUNT, g_lApplicationInstances, FALSE);   }   switch (uMsg) {      chHANDLE_DLGMSG(hWnd, WM_INITDIALOG, Dlg_OnInitDialog);      chHANDLE_DLGMSG(hWnd, WM_COMMAND,    Dlg_OnCommand);   }   return(FALSE);}///////////////////////////////////////////////////////////////////////////////int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR, int) {   // Get the numeric value of the systemwide window message used to notify    // all top-level windows when the module's usage count has changed.   g_uMsgAppInstCountUpdate =      RegisterWindowMessage(TEXT("MsgAppInstCountUpdate"));   // There is another instance of this application running   InterlockedExchangeAdd(&g_lApplicationInstances, 1);   DialogBox(hInstExe, MAKEINTRESOURCE(IDD_APPINST), NULL, Dlg_Proc);   // This instance of the application is terminating   InterlockedExchangeAdd(&g_lApplicationInstances, -1);   // Have all other instances update their display   PostMessage(HWND_BROADCAST, g_uMsgAppInstCountUpdate, 0, 0);   return(0);}//////////////////////////////// End of File //////////////////////////////////

2 映射到記憶體的資料檔案
使用記憶體對應檔1 建立或者開啟檔案核心對象CreateFile 建立或者開啟一個檔案,函數詳情見MSDN
2 建立一個檔案對應記憶體對象HANDLE
WINAPI
CreateFileMappingA(
    __in     HANDLE hFile,   建立的檔案核心對象
    __in_opt LPSECURITY_ATTRIBUTES lpFileMappingAttributes, 安全屬性一般為NULL
    __in     DWORD flProtect,  保護屬性
    __in     DWORD dwMaximumSizeHigh, 檔案大小高位元組,檔案大於4G,才需要用到
    __in     DWORD dwMaximumSizeLow,  檔案大小低位元組,相當於檔案大小,如果這個2個參數都為0,使用檔案核心對象的檔案大小
    __in_opt LPCSTR lpName 檔案對應物件名稱,可以用來在不同進程間共用
    );
3 把檔案對應物件的資料對應到進程地址空間LPVOID
WINAPI
MapViewOfFile(
    __in HANDLE hFileMappingObject, // 檔案對應核心對象
    __in DWORD dwDesiredAccess, 存取權限
    __in DWORD dwFileOffsetHigh, 檔案位移量高位元組
    __in DWORD dwFileOffsetLow, 低位元組,必須是64KB整數倍
    __in SIZE_T dwNumberOfBytesToMap 需要映射的位元組大小
    );
MapVieOfFileEx 可以用於記憶體對應檔是鏈表的情況。

用完記憶體映射對象後,必須清理釋放。1 取消進程地址空間到檔案對應物件的關聯BOOL UnmapViewOfFile(PLVOID pvBaseAddress);參數是調用MapViewOfFile返回的地址。
2 關閉檔案對應核心對象CloseHandle3 關閉檔案核心對象CloseHandle
範例程式碼:
// MemoryMapFile.cpp : Defines the entry point for the console application.//#include <Windows.h>#include <process.h>#include <tchar.h>int _tmain(int argc, _TCHAR* argv[]){int len = sizeof(TCHAR);HANDLE hFile = CreateFile(TEXT("1.txt"),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);DWORD dwSize = GetFileSize(hFile,NULL);//建立檔案對應記憶體HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE,0,dwSize + 1,NULL);//建立映射視圖LPSTR lpstr = (LPSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0,/*檔案指標位移量*/0,0 /*Use fileSize*/);lpstr[dwSize] = 0;_strrev(lpstr);//重新整理視圖FlushViewOfFile(lpstr, 10);//斷開視圖映射UnmapViewOfFile(lpstr);CloseHandle(hMapFile);SetFilePointer(hFile,dwSize,NULL,FILE_BEGIN);SetEndOfFile(hFile);CloseHandle(hFile);return 0;}

用記憶體對應檔在進程中共用資料

以頁分頁檔為儲存空間的記憶體對應檔
在調用CreateFileMapping時,第一個參數傳 INVALID_HANDLE_VALUE就可以了,大小是參數4,參數5.

// MemoryMapFile.cpp : Defines the entry point for the console application.//#include <Windows.h>#include <process.h>#include <tchar.h>#include <stdio.h>int _tmain(int argc, _TCHAR* argv[]){const DWORD dwSize = 4 * 1024;//建立檔案對應記憶體HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,0,dwSize,TEXT("111"));if(ERROR_ALREADY_EXISTS == GetLastError()){printf("exists\n");hMapFile = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, TEXT("111"));//建立映射視圖PTCHAR lpstr = (PTCHAR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0,/*檔案指標位移量*/0,0 /*Use fileSize*/);printf("%S\n",lpstr);goto leave;}//建立映射視圖PTCHAR lpstr = (PTCHAR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0,/*檔案指標位移量*/0,0 /*Use fileSize*/);_tcscpy(lpstr,TEXT("123456"));//重新整理視圖FlushViewOfFile(lpstr, 10);leave://斷開視圖映射UnmapViewOfFile(lpstr);getchar();CloseHandle(hMapFile);return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.