【问题标题】:Unable to capture standard output of process using Boost.Process无法使用 Boost.Process 捕获进程的标准输出
【发布时间】:2010-03-16 20:11:33
【问题描述】:

目前正在使用 Boost 沙箱中的 Boost.Process,但无法正确捕获我的标准输出;想知道是否有人可以给我第二双眼球,看看我可能做错了什么。

我正在尝试使用 DCRAW(最新版本)从 RAW 相机图像中提取缩略图,并捕获它们以转换为 QT QImage。

进程启动函数:

namespace bf = ::boost::filesystem; 
namespace bp = ::boost::process;

QImage DCRawInterface::convertRawImage(string path) {
    // commandline:  dcraw -e -c <srcfile>  -> piped to stdout.
    if ( bf::exists( path ) ) {
        std::string exec = "bin\\dcraw.exe";

        std::vector<std::string> args;
        args.push_back("-v");
        args.push_back("-c");
        args.push_back("-e");
        args.push_back(path);

        bp::context ctx;
        ctx.stdout_behavior = bp::capture_stream();

        bp::child c = bp::launch(exec, args, ctx);

        bp::pistream &is = c.get_stdout();
        ofstream output("C:\\temp\\testcfk.jpg");
        streamcopy(is, output);
    }
    return (NULL);
}


inline void streamcopy(std::istream& input, std::ostream& out) {
    char buffer[4096];
    int i = 0;
    while (!input.eof() ) {
        memset(buffer, 0, sizeof(buffer));
        int bytes = input.readsome(buffer, sizeof buffer);
        out.write(buffer, bytes);
        i++;
    }
}

调用转换器:

DCRawInterface DcRaw;
DcRaw.convertRawImage("test/CFK_2439.NEF"); 

目标是简单地验证我可以将输入流复制到输出文件。

目前,如果我注释掉以下行:

    args.push_back("-c");

然后 DCRAW 将缩略图写入名称为 CFK_2439.thumb.jpg 的源目录,这向我证明了使用正确的参数调用了该过程。没有发生的是正确连接到输出管道。

FWIW:我在 Eclipse 3.5/Latest MingW (GCC 4.4) 下的 Windows XP 上执行此测试。

[更新]

从调试来看,当代码到达 streamcopy 时,文件/管道似乎已经关闭 - bytes = input.readsome(...) 永远不会是 0 以外的任何值.

【问题讨论】:

  • 可能不是主要问题,但output``ofstream 应该以二进制模式打开。另外:streamcopy 可以简化为out &lt;&lt; input.rdbuf();
  • 很好地调用 input.rdbuf()。在我编写 streamcopy 以查看引擎盖下发生了什么之前,我实际上是在使用它。

标签: c++ windows boost io-redirection


【解决方案1】:

我认为您需要正确重定向输出流。在我的应用程序中,这样的工作:

[...]

bp::command_line cl(_commandLine);
bp::launcher l;

l.set_stdout_behavior(bp::redirect_stream);
l.set_stdin_behavior(bp::redirect_stream);
l.set_merge_out_err(true);

bp::child c = l.start(cl);
bp::pistream& is = c.get_stdout();

string result;
string line;
while (std::getline(is, line) && !_isStopped)
{
    result += line;
}

c.wait();

[...]

如果我没记错的话,如果没有重定向,stdout 将无处可去。如果您想获得整个输出,最好等待进程结束。

编辑:

我在 Linux 上可能使用了旧版本的 boost.process。我意识到您的代码与我给您的 sn-p 相似。 c.wait() 可能是关键...

编辑:Boost.process 0.1 :-)

【讨论】:

    【解决方案2】:

    如果迁移到“最新”的 boost.process 不是问题(您肯定知道,这个库有几个变体),您可以使用以下 (http://www.highscore.de/boost/process0.5/)

    file_descriptor_sink sink("stdout.txt");
    execute(
        run_exe("test.exe"),
        bind_stdout(sink)
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2013-01-22
      • 2019-10-01
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      • 2020-10-18
      相关资源
      最近更新 更多