进程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.
可以共享的是非指针的用户自定义类型, 以及内建类型等,不包括含有指针的各种类型。