Windows进程通信有很多种方式:消息、共享内存、匿名管道、命名管道、邮槽、Windows套接字等多种技术。下面介绍共享内存的进程之间的通信。
共享内存方式可以理解为在内存中存放一段空间,服务器申请得到并对空间进行标识,然后客户端根据标识来访问这段共享的内存空间。具体的操作方式是:
在客户端调用函数CreateFileMapping,创建一个带有名字标识的共享内存:
HANDLE CreateFileMapping(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
);
hFile,共享内存句柄;第二个参数为安全属性,一般为默认,第三个参数设置共享内存是可读PAGE_READONLY,可写PAGE_WRITECOPY还是可读可写的PAGE_READWRITE。第四、五个参数是共享内存的大小,最后一个为共享内存的名字。在创建文件映射对象后,服务器端进程调用MapViewOfFile函数映射到本进程的地址空间内;
在客户端调用函数OpenFileMapping,打开共享内存,对共享内存进行操作。
HANDLE OpenFileMapping(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
如果客户端进程获得共享内存对象的句柄成功,则调用MapViewOfFile函数来映射对象视图。用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的。
下面给出一个具体的例子:
服务端:
HANDLE hShareWrite;
//创建文件映射
hShareWrite = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
100, // buffer size
_T("ShareReadWrite")); // name of mapping object
if (hShareWrite == NULL || hShareWrite == INVALID_HANDLE_VALUE)
{
cout<<_T("创建文件映射失败!")<<endl;
return 0;
}
TCHAR* buffer = NULL;
buffer = (TCHAR*)MapViewOfFile(hShareWrite,FILE_MAP_ALL_ACCESS,0,0,100);
if (buffer == NULL)
return 0;
TCHAR str[] = _T("文件共享内存示例!");
memcpy(buffer,str,sizeof(str));
UnmapViewOfFile(buffer);
客户端:
HANDLE hShareRead;
hShareRead = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("ShareReadWrite"));
if (hShareRead == NULL || hShareRead == INVALID_HANDLE_VALUE)
{
cout<<_T("打开文件映射失败!")<<endl;
return 0;
}
TCHAR *buffer = NULL;
buffer = (TCHAR*)MapViewOfFile(hShareRead,FILE_MAP_ALL_ACCESS,0,0,100);
if (buffer == NULL)
return 0;
cout<<buffer[0]<<endl;
UnmapViewOfFile(buffer);
CloseHandle(hShareRead);