简体   繁体   English

为什么_popen在这里起作用,但boost :: process却不起作用?

[英]Why does _popen work here, but boost::process does not?

I have the following working code using _popen, on windows, 我在Windows上使用_popen拥有以下工作代码,

m_pGNUPlot = _popen("/gnuplot/bin/gnuplot.exe", "w");
fprintf(m_pGNUPlot, "set term win\n");
fprintf(m_pGNUPlot, "set term pngcairo\n"); 
fprintf(m_pGNUPlot, "plot \"\Data.txt\" using 1:2 notitle\n"); 
fprintf(m_pGNUPlot, "set output \"\Out.png\"\n");
fprintf(m_pGNUPlot, "replot\n");
fflush(m_pGNUPlot);

But the problem with this is that cmd window keeps poping up, and there is no way to prevent that ( Link ) So, I write the equivalent code in boost::process 但是问题是cmd窗口不断弹出,并且没有办法阻止( Link )所以,我在boost :: process中编写了等效的代码

bp::pipe m_Write;
bp::environment env = boost::this_process::environment();
m_Plot = new bp::child("/gnuplot/bin/gnuplot.exe", bp::std_in < m_Write, env, boost::process::windows::hide);
m_Write.write("set term win\n", sizeof(char)*14);
m_Write.write("set term pngcairo\n", sizeof(char) * 19);    
m_Write("plot \"\Data.txt\" using 1:2 notitle\n", sizeof(char)*35);
m_Write("set output \"\Out.png\"\n", sizeof(char)*22);
m_Write.write("replot\n", sizeof(char) * 8);

So, my question is - are the two code snippets equivalent? 所以,我的问题是-两个代码段是否等效? And if so, why might the second one not work? 如果是这样,为什么第二个不起作用?

I don't have windows, so I tested it on my linux box, slightly simplified: 我没有Windows,因此我在Linux盒子上对其进行了测试,略有简化:

#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

int main() {
    bp::opstream m_Write;
    boost::filesystem::path program("/usr/bin/gnuplot");
    bp::child m_Plot(program, bp::std_in = m_Write);

    m_Write << "set term png\n";
    m_Write << "set output \"Out.png\"\n";
    m_Write << "plot \"Data.txt\" using 1:2 notitle\n";
    m_Write.flush();
    m_Write.pipe().close();

    m_Plot.wait();
    std::cout << "Done, exit code: " << m_Plot.exit_code() << "\n";
}

Prints: 打印:

Done, exit code: 0

And created this nice image from simplistic data : 并通过简单的数据创建了这张漂亮的图片:

Windows 视窗

On windows, leverage the power of Boost Filesystem's path to do the path: 在Windows上,利用Boost Filesystem path功能执行以下操作:

boost::filesystem::path program("C:\\gnuplot\\bin\\gnuplot.exe");

Other Notes 其他注意事项

If the whole script is, indeed, fixed, consider using a raw literal: 如果整个脚本确实是固定的,请考虑使用原始文字:

m_Write << R"(set term png
    set output "Out.png"
    plot "Data.txt" using 1:2 notitle)" << std::flush;
m_Write.pipe().close();

Yes, thank you sehe! 是的,谢谢你! Boost is powerful, but lack of tutorials and examples make it hard to get started with. Boost功能强大,但是由于缺少教程和示例,因此很难入门。

Yes, so the final working code for me - 是的,所以对我来说最后的工作代码是-

bp::opstream m_Write; //output stream to pipe   
boost::filesystem::path program("/gnuplot/bin/gnuplot.exe");
m_Plot = new bp::child(program, bp::std_in = m_Write, bp::windows::hide); //this solves the problem with _popen
m_Write << "set term png\n";
m_Write << "set term pngcairo\n"; 
m_Write << "set output \"" + ToPosixPath(sPath) + "\"\n"; //Notice how this works with std::string :)
m_Write << "plot  \"" + CreateTemp(X, Y) + "\" using 1:2 notitle\n";
m_Write << "exit\n";
m_Write.flush();
m_Write.pipe().close();

m_Plot->wait(); //boost doc states "The call to wait is necessary, to obtain it and tell the operating system, that no one is waiting for the process anymore."
delete m_Plot;

Some points- 一些要点-

  • In windows the exe that supports pipes in gnuplot.exe itself, whereas in linux there are two - gnuplot.exe and pgnuplot.exe. 在Windows中,支持gnuplot.exe本身的管道的exe,而在Linux中,有两个-gnuplot.exe和pgnuplot.exe。

  • Be sure to test your scripts in the GUI, this code fails silently! 确保在GUI中测试您的脚本,此代码会以静默方式失败! Return code will be 0. 返回码将为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM