4 进程间通信的一般方法
解决以上问题的一般方法是在动态链接库中创建一个“共享”部分,写入如下代码:
#pragma data_seg(“Shared”)
HHOOK g_hHook = NULL;
#pragma data_seg()
#pragma comment(linker, “/section:Shared,rws”)
简单地说这几行代码创建了一个共享的变量,如果5个进程载入这个动态链接库,5个进程都有访问的权限。但这个方法有一些问题:一是一些编译器可能并不支持这种方法。二是如果未来的windows版本发生了改变,这种方法就行不通。三是这个方法没有规定线程同步,如果有多线程访问这个变量,线程同步是非常重要的,没有线程间的同步可能会触发诸如冲突等一些问题。解决这个问题的方法是利用内存映像文件(MMF)。
5 内存映像文件(MMF)
在WIN32中,通过使用映像文件在进程间实现共享文件或内存共享,如果利用相同的映像名字或文件句柄,则不同的进程可以通过一个指针来读写同一个文件或者同一内存数据块,并把他们当成该进程内存空间的一部分。内存映像文件可以映射一个文件、一个文件中的指定区域或者指定的内存块,其中的数据就可以用内存读取指令来直接访问,而不用频繁的使用操作文件的I/O系统函数,从而提高文件的存取速度和效率。
映像文件的另一个重要作用就是用来支持永久命名的共享内存。要在两个应用程序之间共享内存,可以在一个应用程序中创建一个文件并映射,然后另外一个程序通过打开和映射此文件,并把它当作自己进程的内存来使用。
6 建立基于MMF的类CIPC
运用内存映像文件解决进程间通信问题,并且创建一个互斥变量来解决线程的同步问题。所有这些封装在一个CIPC的类中。通过运用内存映像文件解决了不同编译器的兼容问题,因为使用的都是标准Win32 API。加上MMF支持进程间的数据共享,在未来的windows版本中微软不会改变MMF的定义及方法。并且互斥变量保持了线程访问的同步。以下给出CIPC的类定义。
class CIPC
{
public:
CIPC();
virtual ~CIPC();
bool CreateIPCMMF(void);//创建一个进程间通信的MMF
bool OpenIPCMMF(void);//打开一个进程间通信的MMF
void CloseIPCMMF(void);//关闭一个进程间通信的MMF
bool IsOpen(void) const {return (m_hFileMap != NULL);}//判断MMF是否打开
bool ReadIPCMMF(LPBYTE pBuf, DWORD &dwBufSize);//读MMF
bool WriteIPCMMF(const LPBYTE pBuf, const DWORD dwBufSize);//写MMF
bool Lock(void);//进入临界区,创建互斥信号量
void Unlock(void);//退出临界区,撤消互斥信号量
protected:
HANDLE m_hFileMap;//MMF文件句柄
HANDLE m_hMutex;//互斥变量句柄
};
7 利用WM_COPYDATA消息来解决进程间的通信