一、进程通信有几种方法:
1.通过剪贴板
2.使用匿名管道
3.命名管道
4.邮槽
二、实现
1.剪贴板:
COleDataSource::SetClipboard()
COleDataSource::GetClipboardOwner()
COleDataSource::Empty()
GlobalAlloc();
GlobalLock();
GlobalUnlock()
..........以上API函数即可,代码略
2.匿名管道:(部分代码如下)
void CMyView::OnCreate()
{
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
int err=CreatePipe(&hRead,&hWrite,&sa,0);
if(err==0)
{
MessageBox("Create Pipe Error !");
return ;
}
STARTUPINFO si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
si.dwFlags=STARTF_USESTDHANDLES;
si.hStdInput=hRead;
si.hStdOutput=hWrite;
si.hStdError=GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION pi;
if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,
NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
{
CloseHandle(hRead);
CloseHandle(hWrite);
hRead=NULL;
hWrite=NULL;
MessageBox("创建子进程失败 !");
return ;
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
void CMyView::OnWrite()
{
char buf[]="Hello ! 我是父进程!";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("Write Error !");
return ;
}
}
void CMyView::OnRead()
{
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
MessageBox("Read Error !");
return ;
}
MessageBox(buf);
}
3.命名管道
命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。
void CNameedPipeClientView::OnConnect()
{
if(!WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER))
{
MessageBox("当前没有可以利用的命名管道 !");
return ;
}
hPipe=CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("打开命名管道失败 !");
hPipe=NULL;
return ;
}
}
void CNameedPipeClientView::OnRead()
{
char buf[100];
DWORD dwRead;
if(!ReadFile(hPipe,buf,100,&dwRead,NULL))
{
MessageBox("Read Error !");
return ;
}
MessageBox(buf);
}
void CNameedPipeClientView::OnWrite()
{
char buf[]="Hello ! 我是子进程!";
DWORD dwWrite;
if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("Write Error !");
return ;
}
}
4.邮槽
服务器端:
void CMailSlotView::OnRecv()
{
HANDLE hMailSlot;
hMailSlot=CreateMailslot("\\\\.\\mailslot\\MyMailSlot",0,MAILSLOT_WAIT_FOREVER,NULL);
if(INVALID_HANDLE_VALUE==hMailSlot)
{
MessageBox("创建邮槽失败 !");
return ;
}
char buf[100];
DWORD dwRead;
if(!ReadFile(hMailSlot,buf,100,&dwRead,NULL))
{
MessageBox("Read Error !");
CloseHandle(hMailSlot);
return ;
}
MessageBox(buf);
CloseHandle(hMailSlot);
}
客户端:
void CMaiSlot_ClientView::OnSend()
{
HANDLE hMailSlot;
hMailSlot=CreateFile("\\\\.\\mailslot\\MyMailSlot",
GENERIC_WRITE,FILE_SHARE_READ,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hMailSlot)
{
MessageBox("打开油槽失败!");
CloseHandle(hMailSlot);
return ;
}
char buf[]="Hello ! 油槽发送数据!";
DWORD dwWrite;
if(!WriteFile(hMailSlot,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("Write Error !");
CloseHandle(hMailSlot);
return ;
}
CloseHandle(hMailSlot);
}