在VC++中创建匿名管道

noCRUDer 2011-08-29 10:08:22
使用MFC创建匿名管道时出现一些问题,我是按照孙鑫老师的VC++深入详解的第17课的例子里面的步骤写的
代码和书上的完全一样,没有哦发现有什么不同的地方
但是第一次创建管道的时候在建立子进程时,子进程无法获取父进程的读写管道的句柄,但是当我再次创建管道时,子进程能够读取父进程的低些句柄,但是读取到的却是第一次创建管道时父进程的读写句柄,即以后每次创建一个子进程,他获得的都是上一个父进程的读写句柄,而不是本次所重新创建的管道的读写句柄。
不知道这是为什么?

书上的步骤是这样的:
对于父进程:
1、创建匿名管道
2、创建子进程
3、编写写入数据到管道的代码;
4、编写从管道读取数据的代码;

对于子进程:
1、在建立窗口的时候获取父进程的读写句柄
2、编写相关到写入数据的代码;
3、编写从管道读取数据的代码;


对应的代码如下:

父进程步骤1和2代码
void CParentView::OnPipeCreate()
{
// TODO: Add your command handler code here
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);

STARTUPINFO sui;
PROCESS_INFORMATION pi;

ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);


if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
//CloseHandle(hRead);
//CloseHandle(hWrite);
AfxMessageBox("管道创建失败!");
return;
}

CString str1,str2;
str1.Format("hRead=%d",hRead);
str2.Format("hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2);

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,true,0,NULL,NULL,&sui,&pi))
{
CloseHandle(hRead);
CloseHandle(hWrite);
hRead=NULL;//防止在析构函数中再次调用CloseHandle
hWrite=NULL;
AfxMessageBox("进程创建失败!");
return;
}
else
{
CloseHandle(pi.hProcess);//在这里关闭
CloseHandle(pi.hThread);
}
}

父进程步骤3代码
void CParentView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="父类数据!";
DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("写入管道失败!");
return;
}
}
父进程步骤4代码
void CParentView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
}

AfxMessageBox(buf);
}

子进程代码:
子进程步骤1代码

void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

if(INVALID_HANDLE_VALUE ==hRead)
AfxMessageBox("hRead获取失败!");
if(INVALID_HANDLE_VALUE ==hWrite)
AfxMessageBox("hWrite获取失败!");

CString str1,str2;
str1.Format("child hRead=%d",hRead);
str2.Format("Child hWrite=%d",hWrite);
AfxMessageBox(str1);
AfxMessageBox(str2);
}


子进程步骤2代码

void CChildView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="child write pipe";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
AfxMessageBox("管道写入失败!");
return;
}

}


子进程步骤3代码

void CChildView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
AfxMessageBox("读取管道失败!");
return;
}
AfxMessageBox(buf);
}










...全文
190 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
noCRUDer 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
你至少也调试一下,看看哪个函数调用失败?失败的原因又是什么?
[/Quote]
从我自己的调试结果看是在子进程的OnInitialUpdate()中执行GetStdHandle(STD_INPUT_HANDLE)时没能获取需要的句柄,在第二次启动子进程时才能获取上一次的句柄,我比较菜,没有找到原因
jixiang1983 2011-08-30
  • 打赏
  • 举报
回复
恭喜LZ,可以结贴了
Eleven 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qingtingchen1987 的回复:]
发现问题了,之所以出现上面的情况是应为在给STARTUPINFO sui这个变量赋值时由于还没有条用CreatePipe()来创建管道,故没有获取需要的hRead和hWrite的值(由于在构造函数中赋值为NULL)从而sui.hStdInput=hRead和sui.hStdOutput=hWrite时他们都为零,直到下次调用时才会取得这次的句柄值。应该将以下代码写在CreatePipe()之后:
……
[/Quote]
恭喜,呵呵~
noCRUDer 2011-08-30
  • 打赏
  • 举报
回复
发现问题了,之所以出现上面的情况是应为在给STARTUPINFO sui这个变量赋值时由于还没有条用CreatePipe()来创建管道,故没有获取需要的hRead和hWrite的值(由于在构造函数中赋值为NULL)从而sui.hStdInput=hRead和sui.hStdOutput=hWrite时他们都为零,直到下次调用时才会取得这次的句柄值。应该将以下代码写在CreatePipe()之后:
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
Eleven 2011-08-29
  • 打赏
  • 举报
回复
你至少也调试一下,看看哪个函数调用失败?失败的原因又是什么?

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧