進程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;
}
進程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)
這是兩個比較簡單的文件映射例子,其中進程1為源進程,而進程2為目的進程。進程1與進程2進行通信,并且共享一個窗口對象,記得在游戲里面會有很多窗口對象的,因此,在與游戲進行通信的時候就可以共享窗口對象。前段時間在做自動化測試的時候,就經常要與客戶端進行一些交互操作,比如,獲得某個窗口的按鈕狀態,以及文本的信息等,不過這樣做的代價是兩個進程要共享一部分頭文件,起碼像我兩個進程里面都用到了兩段相同的頭文件代碼,不然可能就出現某個窗口對象或者控件對象未聲明或者未定義。
2)
另外值得說明的是進程1里面的getchar()用法,很多時候,這個用來延遲操作,并且防止運行過快,特別是在很簡單的結果輸出中,結果會一閃而過,這個時候getchar就起作用了。這里的getchar所起的作用也是延遲的,不過如果將這個getchar()去掉的話,那么你就很可能得到GetLastError()錯誤代碼為2。ERROR_FILE_NOT_FOUND.這個原因是在建立文件對象以后,沒有一段時間緩沖的話,那么進程2有可能找不到在進程空間里面的文件映射,因此就會說ERROR_FILE_NOT_FOUND的錯誤。
3)
之前認為共享內存嘛,應該是可以共享任何對象的,但是我在共享一個deque的時候,發現錯了,后來才發現文件映射不能共享指針的,deque是STL的一個序列式容器,而其內部都是一系列的指針組成的,后來在msdn上面發現了一段這樣的話,很震驚:
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.
可以共享的是非指針的用戶自定義類型, 以及內建類型等,不包括含有指針的各種類型。