Windows平台下常用进程间通信的实现方式

来源:计算机等级考试    发布时间:2012-08-29    计算机等级考试视频    评论

  编辑特别推荐:

  全国计算机等级考试(等考)指定教材

  全国计算机等级考试学习视频

  全国计算机等级考试网上辅导招生

  全国计算机等级考试时间及科目预告

  考试大教育全国计算机等级考试在线测试平台

  全国计算机等级考试资料下载

  全国计算机等级考试论坛

  计算机等级考试四级应用题解析汇总

  2009年下半年全国计算机二级考试报名时间从6月1日起已经开始报名。详情点击:2009年下半年全国计算机等级考试各地报名点汇总。2009年下半年全国计算机二级考试时间是2009年9月19日至23日。更多优质资料尽在考试大论坛 考试大在线题库

  Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式、共享文件方式、共享内存方式、共享数据段、映射文件方式、管道方式、剪贴板方式、消息方式。其中注册表方式需要增加注册表表项,而注册表一般不应删改,所以此种方式不被推荐;共享数据段需要借助动态链接库,实现起来比较麻烦,这种方式也不被推荐。下面重点介绍一下其它几种进程间通信的实现方式。
  1.共享文件方式
  (1)数据发送
  数据发送进程为通过Cfile类创建一个共享文件,然后调用Write()方法想文件中写入数据,具体代码如下:
  void CSendDlg::OnSend()
  {
  //TODO: 在此添加控件通知处理程序代码
  UpdateData(TRUE); //更新数据
  CFile file;
  CString filename = _T("C://test.txt");
  if (file.Open(filename , CFile::modeCreate | CFile::modeWrite | CFile::shareDenyRead))
  {
  char * buf = (char*)(LPCTSTR)m_strsend;
  file.Write(buf, strlen(buf));
  file.Close();
  }
  else
  {
  MessageBox(_T("创建文件失败!"));
  }
  }
  (2)数据接收
  数据在接收进程中,通过Cfile类打开以上创建的共享文件,然后调用Read方法读取数据,具体代码如下:
  void CRecieveDlg::Onrecieve()
  {
  //TODO: 在此添加控件通知处理程序代码
  CFile file;
  CString filename = _T("C://test.txt");
  if (file.Open(filename , CFile::modeRead|CFile::shareDenyWrite))
  {
  char Buf[100]={0};
  file.Read(Buf,100);
  m_strrecieve=Buf;
  file.Close();
  }
  else
  {
  MessageBox(_T("打开文件失败!"));
  }
  UpdateData(FALSE); //更新数据
  }
  2.共享内存方式
  通过内存来传递数据,必须在内存中申请一定的空间。可以调用GlobalAlloc()或者VirtualAllocEx()来实现内存空间分配,使用内存读写函数ReadProcessMemory()和WriteProcessMemory()来读写进程的内存。要使接收程序获得发送程序的内存地址,可以通过发送消息方法来实现,即通过消息把内存地址从发送程序传递到接收程序。
  (1)数据发送
  首先要使用发送消息的方法来传递指针,就需要定义一个用户消息。可用如下的自定义消息来传递指针:
  const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");
  寻找接收数据的程序Recieve的窗口指针pWnd和进程句柄hProcess,用VirtualAllocEx()函数在这个进程中申请虚拟内存空间。然后通过WriteProcessMemory()把字符串m_strsend存放入虚拟内存中,并且通过消息wm_nMemMsg把所申请的内存空间起始地址发送给数据接收程序。最后,当数据接收程序接收到数据后,用VirtualFreeEx()释放所申请的虚拟内存。
  数据发送函数具体代码如下:
  void CSendDlg::OnSend()
  {
  //TODO: 在此添加控件通知处理程序代码
  UpdateData(TRUE); //更新数据
  CWnd *pWnd=CWnd::FindWindow(NULL,_T("Recieve")); //查找Recieve进程
  if(pWnd==NULL){
  MessageBox(_T("寻找接收消息窗口失败!"));
  return;
  }
  DWORD PID; //获取进程号
  GetWindowThreadProcessId(pWnd->m_hWnd, (DWORD*)&PID );
  HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS,FALSE,PID);
  LPVOID lpBaseAddress; //分配虚拟内存
  lpBaseAddress = VirtualAllocEx(hProcess, 0, BUFFER_SIZE,
  MEM_COMMIT, PAGE_READWRITE);
  char data[BUFFER_SIZE];
  strcpy(data,m_strsend);
  //把字符串写入hProcess进程的内存
  WriteProcessMemory(hProcess, lpBaseAddress, data, BUFFER_SIZE, NULL);
  //发送基址给Recieve进程
  pWnd->SendMessage(wm_nMemMsg,NULL,(LPARAM)lpBaseAddress);
  Sleep(100); //等待接收程序接收数据
  VirtualFreeEx(hProcess,lpBaseAddress, 0, MEM_RELEASE); //释放虚拟内存
  }
  (2)数据接收
  首先需要定义一个用户消息,如下代码所示:
  const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");
  然后在头文件中添加消息映射函数定义:
  afx_msg void OnRegMemMsg(WPARAM wParam,LPARAM lParam);
  接着需要定义wm_nMemMsg消息映射,它在消息映射表中的表示方法如下:
  BEGIN_MESSAGE_MAP(CDataRecvDlg, CDialog)
  ON_REGISTERED_MESSAGE(wm_nMemMsg,OnRegMemMsg)
  END_MESSAGE_MAP()
  最后在源文件中添加实现消息映射函数,具体代码如下:
  LRESULT CRecieveDlg::OnRegMemMsg(WPARAM wParam,LPARAM lParam)
  {
  //TODO: 在此添加控件通知处理程序代码
  LPVOID lpBaseAddress=(LPVOID)lParam;
  HANDLE hProcess=GetCurrentProcess(); //把字符串写入hProcess进程的内存
  char data[BUFFER_SIZE];
  ReadProcessMemory(hProcess, lpBaseAddress, data,BUFFER_SIZE, NULL);
  m_strrecieve=data;
  UpdateData(FALSE); //更新数据
  return 0;
  }

上一页1234下一页

视频学习

我考网版权与免责声明

① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;

② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。

最近更新

社区交流

考试问答