溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

應用文件映射進行進程間通訊

發(fā)布時間:2020-05-18 06:12:25 來源:網(wǎng)絡 閱讀:466 作者:tiankefeng0520 欄目:移動開發(fā)

文件映射解釋:

(摘抄)內(nèi)存映射文件用來保留一個地址空間,并提交物理存儲器。早期的內(nèi)存映射文件并不是提交物理內(nèi)存供調用者使用,而是提交永久存儲器(外存)上的文件數(shù)據(jù)。當然操作系統(tǒng)會為永久存儲器保留一個讀緩沖區(qū),這樣讀取文件數(shù)據(jù)就快多了。內(nèi)存映射文件的特點使它很適合于加載EXE或DLL文件。這樣可以節(jié)省內(nèi)存又減少了加載所需時間。還可以使用它來映射大容量的文件,這樣就不必在讀取文件數(shù)據(jù)前設置很大的緩沖區(qū)。另外內(nèi)存映射文件常用于進程間通信,也是進程間通信的主要手段,其它進程之間通信機制都是基于內(nèi)存映射文件來實現(xiàn)。為了更快的在進程之間通信,現(xiàn)在的內(nèi)存映射文件也可以提交物理內(nèi)存,這樣內(nèi)存映射文件既可以提交物理內(nèi)存又可以提交文件


應用文件映射進行進程間通信

原來來內(nèi)存映射文件只映射類似磁盤一類的存儲器上的文件。而為了更快速地在進程之間通信,內(nèi)存映射文件還可以提交物理內(nèi)存。實現(xiàn)方法是通過訪問同一個內(nèi)存映射文件對象(映射到物理內(nèi)存),兩個進程或多個進程就能夠訪問到同一塊物理內(nèi)存設進程。


假設進程A和進程B需要通信,那么進程A需要先創(chuàng)建一個內(nèi)存映射文件(之前不必調用CreateFileForMapping函數(shù)來創(chuàng)建文件,因為不需要創(chuàng)建文件)。這個內(nèi)存映射文件可以是在永久存儲器中,也可以是在內(nèi)存中。為了減小通信時間,最好提交物理內(nèi)存。

1.進程A在調用CreateFileMapping函數(shù)時,參數(shù)1指定為INVALID_HANDLE_VALUE,這表示這個內(nèi)存映射文件對象將要把物理內(nèi)存提交到地址空間中。最后一個參數(shù)一定要指定一個名字。

2.進程B也同樣調用CreateFileMapping函數(shù),而且參數(shù)相同。內(nèi)核會根據(jù)名字來判斷是否已經(jīng)存在一個內(nèi)存映射文件對象,如果創(chuàng)建了就返回原來的對象的句柄。

3.獲得地址空間指針 
      MapViewOfFile()
      如果需要進行文件寫入, 可以通過類型轉換直接對于內(nèi)存地址進行賦值, 比如:  memcpy( lpAddress, lpBuf, ....)     如果是讀取操作, 將參數(shù)順序調整一下


  4.卸載內(nèi)存映射文件地址指針 
      UnmapViewOffFile()

 5.關閉內(nèi)存映射文件 
     CloseHandle()


下面這個例子寫進程加載一個位圖并將數(shù)據(jù)寫到內(nèi)存映射文件中,讀進程從內(nèi)存映射文件讀取數(shù)據(jù)并生成新位圖。

寫進程:

 

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "FileHandler.h"

using namespace std;

typedef struct
{
long size;
long bufferAdd;

}SharedData;

SharedData *lpData ;
HANDLE hMemoryMap;

void FreeMemory()
{
if(lpData)
{
::UnmapViewOfFile(lpData);
lpData=NULL;

}
if(hMemoryMap)
{
CloseHandle(hMemoryMap);
hMemoryMap = NULL;
}
}

BYTE* CAlloc(WCHAR* name, long size)
{
FreeMemory();

BYTE* addr;
hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, size, name);
if (hMemoryMap != NULL)
{
addr = (BYTE *)MapViewOfFile(hMemoryMap, FILE_MAP_WRITE, 0, 0, 0);
if (addr == NULL)
{
CloseHandle(hMemoryMap);
hMemoryMap = NULL;
return NULL;
}
if(IsBadWritePtr(addr,size)!=FALSE)
{
::UnmapViewOfFile(addr);
addr = NULL;
::CloseHandle(hMemoryMap);
hMemoryMap = NULL;
}
}
return addr;
}

int _tmain(int argc, _TCHAR* argv[])
{

hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 64, L"DataMap");
if (hMemoryMap != NULL)
{
lpData = (SharedData *)MapViewOfFile(hMemoryMap, FILE_MAP_WRITE, 0, 0, 0);
if (lpData == NULL)
{
CloseHandle(hMemoryMap);
hMemoryMap = NULL;
}
}

FileHandler *h=new FileHandler;
FileInfo file=h->ReadFile("file/Butterfly2.bmp");
lpData =(SharedData *)CAlloc( L"DataMap",sizeof(long)*2+file.size);
lpData->size=file.size;
lpData->bufferAdd=(long)(lpData+sizeof(long)*2);
void * dst=(void *)(lpData+sizeof(long)*2);
memcpy(dst,file.buffer,file.size);
delete file.buffer;
file.buffer=NULL;

std::cout<<"\nwaiting.......";
Sleep(-1);
return 0;
}

 

讀進程:

 

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "FileHandler.h"
using namespace std;

typedef struct
{
    long   size;
    long   bufferAdd;
}SharedInData;

int _tmain(int argc, _TCHAR* argv[])
{
    SharedInData *lpData ;
    HANDLE hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 4096, L"DataMap");
    if (hMemoryMap != NULL)
    {
        lpData =(SharedInData *) MapViewOfFile(hMemoryMap, FILE_MAP_READ, 0, 0, 0);
        if (lpData == NULL)
        {
            CloseHandle(hMemoryMap);
            hMemoryMap = NULL;
        }
    }

    FileHandler *file=new FileHandler;
    file->WriteFile("bitmap.bmp",(char*)lpData->bufferAdd,lpData->size);
    Sleep(-1);
    return 0;
}

 

文件處理類

#include "stdafx.h"
#include "FileHandler.h"
using namespace std;

/*************************************************************************/
/*ofstream: 寫操作(輸出)的文件類 (由ostream引申而來) 
/*ifstream: 讀操作(輸入)的文件類(由istream引申而來) 
/*fstream: 可同時讀寫操作的文件類 (由iostream引申而來) 

ios::in 為輸入(讀)而打開文件 
ios::out 為輸出(寫)而打開文件 
ios::ate 初始位置:文件尾 
ios::app 所有輸出附加在文件末尾 
ios::trunc 如果文件已存在則先刪除該文件 
ios::binary 二進制方式 

seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用這個原型可以指定由參數(shù)direction決定的一個具體的指針開始計算的一個位移(offset)。它可以是:

ios::beg 從流開始位置計算的位移 
ios::cur 從流指針當前位置開始計算的位移 
ios::end 從流末尾處開始計算的位移 


/*************************************************************************/
FileHandler::FileHandler()
{

}

FileHandler::~FileHandler()
{

}

FileInfo FileHandler::ReadFile(char* filename)
{
	FileInfo info;
	char * buffer;        
	long size;        
	ifstream file (filename, ios::in|ios::binary|ios::ate);       
	size = file.tellg();       
	file.seekg (0, ios::beg);      
	buffer = new char [size];   
	
	file.read (buffer, size);      
	file.close();     
	info.size=size;
	info.buffer=buffer;
	//buffer[size]='\0';
	cout << "the complete file is in a buffer:"<<size;   
	return info;
}

bool FileHandler::WriteFile(char* filename,char * buffer,int length)
{


	ofstream file (filename, ios::out|ios::binary|ios::trunc); 
	file.write(buffer,length);
	file.close();
	return true;

}
long FileHandler::GetFileSize(char* filename)
{
	int size=0;
	ifstream file (filename, ios::in|ios::binary|ios::ate);       
	size = file.tellg();       

	file.close(); 
	return size;
}



 

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI