進(jìn)程1:
#define BUF_SIZE 256
char fileMapObjectName[] = "FileMappingObject";
class Sample
{
public:
void set_x(int x){this->xx = x;}
int get_x(){return this->xx;}
Sample(){}
private:
int xx;
};
class EmulatorWindow
{
public:
void set_ew(Sample s){this->sample = s;}
Sample get_ew(){return this->sample;}
EmulatorWindow(){}
private:
Sample sample;
};
int main()
{
HANDLE fileMap = CreateFileMapping(
(HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
BUF_SIZE,
fileMapObjectName);
if (NULL == fileMap || GetLastError() == ERROR_ALREADY_EXISTS)
{
printf("create file mapping fails! the error code is (%d)",GetLastError());
return 0;
}
Sample s;
s.set_x(112);
EmulatorWindow* buffer = (EmulatorWindow*)MapViewOfFile(
fileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
BUF_SIZE);
if (NULL == buffer)
{
printf("mapping view of file fails! the error code is (%d)",GetLastError());
return 1;
}
EmulatorWindow ew;
ew.set_ew(s);
CopyMemory(buffer,&ew,BUF_SIZE);
getchar();
FlushViewOfFile(fileMap,BUF_SIZE);
UnmapViewOfFile(buffer);
buffer = NULL;
CloseHandle(fileMap);
fileMap = NULL;
return 2;
}
進(jìn)程2:
#define BUF_SIZE 256
char fileMapObjectName[] = "FileMappingObject";
class Sample
{
public:
void set_x(int x){this->xx = x;}
int get_x(){return this->xx;}
Sample(){}
private:
int xx;
};
class EmulatorWindow
{
public:
void set_ew(Sample s){this->sample = s;}
Sample get_ew(){return this->sample;}
EmulatorWindow(){}
private:
Sample sample;
};
int main()
{
HANDLE fileMap = OpenFileMapping(
FILE_MAP_ALL_ACCESS,
TRUE,
fileMapObjectName);
if (NULL == fileMap)
{
printf("opening file mapping fails! the error code is (%d)",GetLastError());
return 0;
}
EmulatorWindow* sharedMemory = (EmulatorWindow*)MapViewOfFile(
fileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (NULL == sharedMemory )
{
printf("mapping view of file fails! the error code is (%d)",GetLastError());
return 1;
}
Sample s = sharedMemory->get_ew();
int x = s.get_x();
char buffer[100];
memset(buffer,0,100);
sprintf(buffer,"message box is:(%d)",x);
MessageBox(NULL,buffer,NULL,MB_OK);
UnmapViewOfFile(sharedMemory);
sharedMemory = NULL;
CloseHandle(fileMap);
fileMap = NULL;
return 3;
}
1)
這是兩個(gè)比較簡單的文件映射例子,其中進(jìn)程1為源進(jìn)程,而進(jìn)程2為目的進(jìn)程。進(jìn)程1與進(jìn)程2進(jìn)行通信,并且共享一個(gè)窗口對(duì)象,記得在游戲里面會(huì)有很多窗口對(duì)象的,因此,在與游戲進(jìn)行通信的時(shí)候就可以共享窗口對(duì)象。前段時(shí)間在做自動(dòng)化測試的時(shí)候,就經(jīng)常要與客戶端進(jìn)行一些交互操作,比如,獲得某個(gè)窗口的按鈕狀態(tài),以及文本的信息等,不過這樣做的代價(jià)是兩個(gè)進(jìn)程要共享一部分頭文件,起碼像我兩個(gè)進(jìn)程里面都用到了兩段相同的頭文件代碼,不然可能就出現(xiàn)某個(gè)窗口對(duì)象或者控件對(duì)象未聲明或者未定義。
2)
另外值得說明的是進(jìn)程1里面的getchar()用法,很多時(shí)候,這個(gè)用來延遲操作,并且防止運(yùn)行過快,特別是在很簡單的結(jié)果輸出中,結(jié)果會(huì)一閃而過,這個(gè)時(shí)候getchar就起作用了。這里的getchar所起的作用也是延遲的,不過如果將這個(gè)getchar()去掉的話,那么你就很可能得到GetLastError()錯(cuò)誤代碼為2。ERROR_FILE_NOT_FOUND.這個(gè)原因是在建立文件對(duì)象以后,沒有一段時(shí)間緩沖的話,那么進(jìn)程2有可能找不到在進(jìn)程空間里面的文件映射,因此就會(huì)說ERROR_FILE_NOT_FOUND的錯(cuò)誤。
3)
之前認(rèn)為共享內(nèi)存嘛,應(yīng)該是可以共享任何對(duì)象的,但是我在共享一個(gè)deque的時(shí)候,發(fā)現(xiàn)錯(cuò)了,后來才發(fā)現(xiàn)文件映射不能共享指針的,deque是STL的一個(gè)序列式容器,而其內(nèi)部都是一系列的指針組成的,后來在msdn上面發(fā)現(xiàn)了一段這樣的話,很震驚:
Do not store pointers in the memory mapped file; store offsets from the base of the file mapping so that the mapping can be used at any address.
可以共享的是非指針的用戶自定義類型, 以及內(nèi)建類型等,不包括含有指針的各種類型。