什么是进程?
进程是一个正在运行的程序的实例,主要由两部分组成:
(1)一个操作系统用来管理进程的内核对象。
(2)创建时系统所分配的资源,主要是内存地址空间。
什么是进程间的通信?
进程间通信是指在多进程环境下,使用的数据交互、事件通知等方法使各进程协同工作。
进程间通信常用的方式有哪几种?
常用的有4种:消息传递、共享内存、管道、剪贴板:
(1)消息传递:不以进程为界限,处理消息的是窗体(包括子窗体、控件等),而与是否在同一进程无关。
(2)共享内存:在一个进程内创建内存映射,却能够在其他都个进程中使用。这些进程共享的是物理存储器的同一个页面,在把这些物理内存映射到虚拟内存时各个进程的虚拟地址并不一定相同。当一个进程将数据写入共享内存时,其他进程可以立即获取数据变更情况。
(3)管道和邮槽:其实是对共享内存的两种不同的封装机制。
(4)剪贴板:Windows系统支持剪贴板IPC的基本机制是由系统预留的一块全局共享内存,可用于被各进程暂时存储数据。写入进程首先创建一个全局内存块,并将数据写到该内存块;接受数据的进程通过剪贴板机制获取此内存块的句柄,并完成对该内存块数据的读取。
如何使用WM_COPYDATA消息通信?
在Win32中,WM_COPYDATA消息主要目的是允许在进程间传递只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。
注意:
(1)WM_COPYDATA消息不能发送HDC、HBITMAP之类的东西,它们对于目标进程来说是无效的。目标进程得到这些数据不能在原进程作任何事情,因为它们属于不同的进程。
(2)由于SendMessage()是阻塞的,只有接收方响应了消息,SendMessage()才能返回,否则一直阻塞。所以,当数据传输过于频繁时将可能导致数据的丢失。
SendMessage(WM_COPYDATA,wParam,lParam);
wParam 设置为包含数据的窗口句柄
lParam 指向一个COPYDATASTRUCT的结构
typedef struct tagCOPYDATASTRUCT{
DWORD dwData; //自定义数据
DWORD cbData; //数据大小
PVOID lpData; //指向数据的指针
}COPYDATASTRUCT;
#实例#
两个窗口程序:基于Dialog的- CDataSendDlg + CDataRecvDlg
********************CDataSendDlg****************
void CDataSendDlg::OnSendCopydata()
{
CString strCopyData = _T("HELLO");
CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 查找DataRecv进程
if (pWnd==NULL)
{
AfxMessageBox("Unable to find DataRecv.");
return;
}
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = strCopyData.GetLength()*sizeof(THAR);
cpd.lpData = (void*)m_strCopyData.GetBuffer(cpd.cbData);
pWnd->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd); // 发送
}
********************CDataRecvDlg****************
BEGIN_MESSAGE_MAP(CDataRecvDlg, CDialog)
//{{AFX_MSG_MAP(CDataRecvDlg)
ON_WM_COPYDATA() //WM_COPYDATA消息的映射
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CDataRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
m_strCopyData=(LPSTR)pCopyDataStruct->lpData;
m_strCopyData=m_strCopyData.Left(pCopyDataStruct->cbData/sizeof(TCHAR)); // 获得实际长度的字符串
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
引自: http://hi.baidu.com/cg%5Fjane/blog/item/5e471e13589640c6c3fd78af.html