Windows平台下常用进程间通信的实现方式计算机二级考试

文章作者 100test 发表时间 2009:06:15 10:08:04
来源 100Test.Com百考试题网


  编辑特别推荐:

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

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

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

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

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

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

  全国计算机等级考试论坛

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

  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.
  }

相关文章


C 系统相关:如何安全终止线程计算机二级考试
Windows平台下常用进程间通信的实现方式计算机二级考试
Qt_e输入法程序设计指南计算机二级考试
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛