问个问题!createprocess和两条管道pipe通信造成的混乱!
描述差不多是这样的,我要在main下边调用createprocess创建一个ffplay.exe,在设置STARTUPINFO结构的时候:
STARTUPINFO siStartInfo;
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_Error;// 错误输出句柄
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;// 输出句柄
siStartInfo.hStdInput = g_hChildStd_IN_Rd;// 输入句柄
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
当然这两个g_hChildStd_IN_Rd和g_hChildStd_OUT_Wr是绑定起来的:
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
现在是这样的:
我要往里面写一个getinfo:
while (!end_write_pipe)
{
if (!write_message.empty())
{
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
}
else
{
Sleep(100);
}
}
然后从另一handle中取出消息,注意这里,需要两次ReadFile才能出现结果,一次什么都读不到:
while (!end_read_pipe)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, &o);
DWORD dwError = GetLastError();
if (!bSuccess && (dwError == ERROR_IO_PENDING))
{
WaitForSingleObject(g_hChildStd_OUT_Rd, INFINITE);
bSuccess = true;
}
if (bSuccess && write_message == "$gw")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break;
if (w == (int)time_total_ms)
{
ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break;
}
write_message.clear();
printf("width : %d, height : %d\n", w, h);
}
else if (bSuccess && write_message == "$gt")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
if (w == (int)time_total_ms)
{
ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
}
write_message.clear();
printf("time_total_ms is : %f\n", time_total_ms);
}
else
{
Sleep(100);
}
memset(chBuf, 0, strlen(chBuf));
}
但是ffplay还接收q和p信息,q为退出,p为暂停和播放,上面的代码,会导致输入p的时候,造成无数次的暂停和播放(也就是反复的写入p)!
注意这里,我觉得更奇葩的是,
把Write改成这样的:
while (!end_write_pipe)
{
if (!write_message.empty())
{
printf("i : %d\n", ++i);
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
}
else
{
Sleep(100);
}
}
ReadFile这样的:
while (!end_read_pipe)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, &o);
DWORD dwError = GetLastError();
if (!bSuccess && (dwError == ERROR_IO_PENDING))
{
WaitForSingleObject(g_hChildStd_OUT_Rd, INFINITE);
bSuccess = true;
}
if (bSuccess && write_message == "$gw")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break;
// if (w == (int)time_total_ms)
// {
// ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
// int i = strlen(chBuf);
// char str[10] = {'\0'};
// memcpy(str, chBuf+2, 3);
// w = atoi(str);
// char str2[10] = {'\0'};
// memcpy(str2, chBuf+6, 3);
// h = atoi(str2);
// if( ! bSuccess || dwRead == 0 ) break;
// }
write_message.clear();
printf("width : %d, height : %d\n", w, h);
}
else if (bSuccess && write_message == "$gt")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
// if (w == (int)time_total_ms)
// {
// ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
// int i = strlen(chBuf);
// char str[10] = {'\0'};
// memcpy(str, chBuf+2, i - 2);
// time_total_ms = atof(str);
// }
write_message.clear();
printf("time_total_ms is : %f\n", time_total_ms);
}
else
{
Sleep(100);
}
memset(chBuf, 0, strlen(chBuf));
}
输出34次i,就不必两次ReadFile了!(如果像上面的代码不读两次 比如第一次获取wh,接着获取time,会出现time的结果是w的value!)
还有一种情况WriteFile的代码:
while (!end_write_pipe)
{
if (!write_message.empty())
{
write_message += "\r\n";
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
//DWORD dwError = GetLastError();
write_message.clear();
}
else
{
Sleep(100);
}
}
p和q正常,但是永远获取不到wh和time!
这是很奇葩的!所以来这边问问!谢谢各位帮我看看,我可能写了一天代码了,一些细节问题没有注意到! CreatePipe WriteFile ReadFile
STARTUPINFO? createprocess
[解决办法]
你可以下载这个参考参考,http://download.csdn.net/detail/xiaohuh421/2682969 VC++实现CMD命令执行与获得返回信息
[解决办法]
比如应该是640&380的,却给我返回了640&380640&380640&380……
这个是正常的,已经说过了,面向流的,本来就是这样。你要自己分包处理,加标记、加每个包长度标识、自己做缓存来黏包
[解决办法]
你的这种情况就是黏包