【IPC程式間通訊之三】記憶體對映檔案Mapping File

Love_Hulidear發表於2014-05-16

IPC程式間通訊+共享記憶體Mapping

      
        IPC(Inter-Process Communication,程式間通訊)。
        檔案對映(Mapping)是一種將檔案內容對映到記憶體地址的技術,通過對對映記憶體,讀寫檔案如同讀寫記憶體一般簡單。
       多個程式對映同一個檔案對映物件,也即多個程式對映到同一個物理儲存頁面,因此,當一個程式向對映記憶體寫入資料時,其他程式可以通過對映記憶體讀取資料,通過這個機制實現程式間通訊。
         
       1.記憶體檔案對映Mapping File :

         A程式建立一個命名的Mapping物件,並在對映記憶體中寫入需要共享的資料。B程式通過物件名開啟Mapping物件,對映該Mapping物件,從對映記憶體中讀取資料。

       2.基本API函式 :
建Mapping物件:
        HANDLE    CreateFileMapping(
                           
HANDLE      hFile,                                   //物理檔案控制程式碼
                           
LPSECURITY_ATTRIBUTES    lpAttributes, //安全設定
                         
 DWORD      flProtect,                                      //保護設定
                           
DWORD      dwMaximumSizeHigh,         //高位檔案大小
                         
 DWORD      dwMaximumSizeLow,          //低位檔案大小
                           
LPCTSTR   lpName                                   //共享記憶體名稱
);
        該函式返回建立的Mapping物件。
建立對映記憶體:
        LPVOID  MapViewOfFile(
                      HANDLE    hFileMappingObject,               //Mapping物件
                         DWORD     dwDesiredAccess,                        //存取類別
                         DWORD     dwFileOffsetHigh,                  //對映檔案高位
                         DWORD     dwFileOffsetLow,                    //對映檔案地位
                         SIZE_T        dwNumberOfBytesToMap       //對映位元組數
);
        該函式用於建立Mapping物件的對映記憶體,返回對映記憶體。
記憶體複製
        VOID  CopyMemory(
                    PVOID Destination,                //要複製記憶體塊的目的地址
                    CONST VOID *Source,              //要複製記憶體塊的源地址
                    SIZE_T Length                                          //複製的位元組數
);
       該函式用於將資料複製到對映記憶體。
開啟Mapping物件:
       HANDLE  OpenFileMapping(
                         DWORD   dwDesiredAccess ,   // 存取許可權
                         BOOL       bInheritHandle ,       //繼承設定,一般設為FALSE
                         LPCTSTR    lpName                  // Mapping物件名
);
      該函式用於開啟一個存在的Mapping物件。返回Mapping物件控制程式碼。
  
       3.牛刀小試:
     先在VC6.0中執行process1程式,在執行process2程式:

         執行效果:

process1程式:
#include 
#include 
#include 
void main()
{
	char szName[]="共享記憶體示例!";
	char szMsg[]="Hello Mapping!";
	//檔案對映控制程式碼
	HANDLE hMapFile;
	//共享資料緩衝區指標
	LPTSTR pBuf;
	//建立命名的檔案對映,不代表任務硬碟上的檔案
	hMapFile = CreateFileMapping(
		INVALID_HANDLE_VALUE,
		NULL, 
		PAGE_READWRITE,
		0,
		256, 
		szName);

	//建立對映記憶體
	pBuf = (LPTSTR) MapViewOfFile(hMapFile,
		FILE_MAP_ALL_ACCESS,
		0,                   
		0,                   
		256);

	//將共享資料複製到檔案對映中
	CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg));
	
	printf("共享記憶體建立完成,按任意鍵取消共享內	存並退出!\n");
	getch();
	//取消對映,退出
	UnmapViewOfFile(pBuf);
	CloseHandle(hMapFile);
}
process2 程式:
#include 
#include 
#include 
/* 預處理申明*/
#pragma comment (lib, "User32.lib")
#define BUF_SIZE 256
/* 全域性變數 */
TCHAR szName[]=TEXT("共享記憶體示例!");
void main()
{
	HANDLE hMapFile;
	LPTSTR pBuf;
	//開啟檔案mapping
	hMapFile = OpenFileMapping(
		FILE_MAP_ALL_ACCESS,
		FALSE,
		szName); 
	if (hMapFile == NULL) 
	{ 
		printf("OpenFileMapping error: %d.\n",  GetLastError());
		return;
	} 
	//對映
	pBuf = MapViewOfFile(hMapFile,
		FILE_MAP_ALL_ACCESS,
		0,                    
		0,                    
		256);  
	if (pBuf == NULL) 
	{ 
		printf("MapViewOfFile error %d\n", GetLastError()); 
		return;
	}
	//訊息得到的共享資料
	printf("共享記憶體資料:  %s\n",pBuf);
	//取消mapping,關閉控制程式碼,返回
	UnmapViewOfFile(pBuf);
	CloseHandle(hMapFile);
}



相關文章