Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows中的二进制管道_Windows_Visual C++_Pipe - Fatal编程技术网

Windows中的二进制管道

Windows中的二进制管道,windows,visual-c++,pipe,Windows,Visual C++,Pipe,我能够创建一个子进程并通过管道传递其stdin和stdout。它在文本模式下工作正常。 但是,当我尝试将子进程中的I/O设置为二进制格式(即没有0x0A到0x0D 0x0A转换)时,子进程失败_setmode返回-1,这已被记录为指示故障。这是为什么?如何解决 父代码类似于以下内容: const std::string path; // = "path_to.exe" PROCESS_INFORMATION info; SECURITY_ATTRIBUTES sec_attr; //in-o

我能够创建一个子进程并通过管道传递其stdin和stdout。它在文本模式下工作正常。 但是,当我尝试将子进程中的I/O设置为二进制格式(即没有0x0A到0x0D 0x0A转换)时,子进程失败_setmode返回-1,这已被记录为指示故障。这是为什么?如何解决

父代码类似于以下内容:

const std::string path;  // = "path_to.exe"
PROCESS_INFORMATION info;
SECURITY_ATTRIBUTES sec_attr;

//in-out from the CHILD process' perspective
HANDLE out_r = nullptr;
HANDLE out_w = nullptr;
HANDLE in_r = nullptr;
HANDLE in_w = nullptr;


sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_attr.lpSecurityDescriptor = NULL;
sec_attr.bInheritHandle = TRUE; //inherit by child processes

if (!CreatePipe(&out_r, &out_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(out_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (!CreatePipe(&in_r, &in_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(in_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (out_r && out_w && in_r && in_w)
{
  startup_info.hStdError = out_w;
  startup_info.hStdOutput = out_w;
  startup_info.hStdInput = in_r;
  startup_info.dwFlags = STARTF_USESTDHANDLES;
}

if (CreateProcessA(path.c_str(), (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &info)
    != TRUE)
{
    DWORD error = GetLastError();
    //error handling
}

// ... read data using ReadFile
int status = _setmode(_fileno(stdin), _O_BINARY);
if (status == -1)
    throw std::exception();

status = _setmode(_fileno(stdout), _O_BINARY);
if (status == -1)
    throw std::exception();

puts("hello from the child process");
子代码类似于以下内容:

const std::string path;  // = "path_to.exe"
PROCESS_INFORMATION info;
SECURITY_ATTRIBUTES sec_attr;

//in-out from the CHILD process' perspective
HANDLE out_r = nullptr;
HANDLE out_w = nullptr;
HANDLE in_r = nullptr;
HANDLE in_w = nullptr;


sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_attr.lpSecurityDescriptor = NULL;
sec_attr.bInheritHandle = TRUE; //inherit by child processes

if (!CreatePipe(&out_r, &out_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(out_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (!CreatePipe(&in_r, &in_w, &sec_attr, 0))
    throw std::exception();
if (!SetHandleInformation(in_r, HANDLE_FLAG_INHERIT, 0))
    throw std::exception();

if (out_r && out_w && in_r && in_w)
{
  startup_info.hStdError = out_w;
  startup_info.hStdOutput = out_w;
  startup_info.hStdInput = in_r;
  startup_info.dwFlags = STARTF_USESTDHANDLES;
}

if (CreateProcessA(path.c_str(), (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &info)
    != TRUE)
{
    DWORD error = GetLastError();
    //error handling
}

// ... read data using ReadFile
int status = _setmode(_fileno(stdin), _O_BINARY);
if (status == -1)
    throw std::exception();

status = _setmode(_fileno(stdout), _O_BINARY);
if (status == -1)
    throw std::exception();

puts("hello from the child process");

我正在看一篇MSDN文章,它提供了一个参考实现,几乎可以说明您在这里要做的事情

我看到的一个细微差别是,父代码的编写位置(第二次调用
SetHandleInformation
()):

MSDN示例(翻译为使用变量名)将编写为:

if (!SetHandleInformation(in_w, HANDLE_FLAG_INHERIT, 0))
如果这个小小的改变没有帮助的话,这里还有几页也值得一看:


我正在看一篇MSDN文章,它提供了一个参考实现,几乎可以说明您在这里要做的事情

我看到的一个细微差别是,父代码的编写位置(第二次调用
SetHandleInformation
()):

MSDN示例(翻译为使用变量名)将编写为:

if (!SetHandleInformation(in_w, HANDLE_FLAG_INHERIT, 0))
如果这个小小的改变没有帮助的话,这里还有几页也值得一看:


对_setmode的哪个调用失败?一个用于标准输入,还是一个用于标准输出,或者两者兼而有之?errno的值是多少?另外,如果从命令行运行子进程,子进程是否以相同的方式失败,例如,
echo hello | child | findstr。
?1)两个调用都失败。2) errno为9,“坏文件”3)在从命令行运行而没有管道输入/输出时可以正常运行。作为Chrome扩展的本机主机,当从命令行运行时,也可以正常运行。我认为现在我需要提供更多的上下文。父进程是一个本机单元测试;它是否通过管道输入和输出从命令行运行?(我想知道的是,问题是否出在孩子身上,或者你创建管道的方式有什么问题。如果你让命令行创建管道,但仍然存在问题,那么问题出在孩子身上,否则就出在父母身上。)但是先修复Phil指出的错误。哪个对_setmode的调用失败了?一个用于标准输入,还是一个用于标准输出,或者两者兼而有之?errno的值是多少?另外,如果从命令行运行子进程,子进程是否以相同的方式失败,例如,
echo hello | child | findstr。
?1)两个调用都失败。2) errno为9,“坏文件”3)在从命令行运行而没有管道输入/输出时可以正常运行。作为Chrome扩展的本机主机,当从命令行运行时,也可以正常运行。我认为现在我需要提供更多的上下文。父进程是一个本机单元测试;它是否通过管道输入和输出从命令行运行?(我想知道的是,问题是否出在孩子身上,或者你创建管道的方式有什么问题。如果你让命令行创建管道,但仍然存在问题,那么问题出在孩子身上,否则就出在家长身上。)但是先修复Phil指出的错误。很好,很高兴能提供帮助!太好了,很高兴帮忙!