Это вопрос о Boost.Process 0.5, а не какой-либо earlier versionКак взаимодействовать с моменты синхронно процесса в Boost.Process 0,5
Пусть у меня есть простая программа, которая попросить ряда и вернуть другой номер, а именно :
// ask.x, simple program with IO
#include<iostream>
int main(){
double n;
std::cout << "number?" << std::endl;
std::cin >> n;
std::cout << n + 1 << std::endl;
}
Теперь я хочу, чтобы взаимодействовать с этой программой programmaticaly с помощью Boost.Process 0,5 (http://www.highscore.de/boost/process0.5/boost_process/tutorial.html). Когда я пытаюсь использовать библиотеку, я не получаю ожидаемого поведения, номер никогда не отправил в программу. (чтение первой строки в порядке). Я попытался написать обобщение примера, описанного в http://www.highscore.de/boost/process0.5/boost_process/tutorial.html#boost_process.tutorial.synchronous_i_o, но я потерпел неудачу.
MWE, в первой половине есть много необходимого шаблона, а также где я думаю, что совершу ошибку.
#include <boost/process.hpp> // version 0.5
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
#define ALSOSEND // for fully interactive case
using namespace boost;
int main() {
// Boilerplate code, see input only example here https://stackoverflow.com/questions/12329065/how-to-bind-program-termination-with-end-of-stream-in-boost-process-0-5
process::pipe pi = boost::process::create_pipe();
process::pipe po = boost::process::create_pipe();
{
iostreams::file_descriptor_sink sink(
pi.sink,
iostreams::close_handle
);
iostreams::file_descriptor_source source(
po.source,
boost::iostreams::close_handle
);
process::execute(
process::initializers::run_exe("./ask.x"),
process::initializers::bind_stdout(sink)
#ifdef ALSOSEND
, process::initializers::bind_stdin(source)
#endif
);
}
iostreams::file_descriptor_source fdsource(pi.source, iostreams::close_handle);
iostreams::stream<iostreams::file_descriptor_source> is(fdsource);
iostreams::file_descriptor_sink fdsink(po.source, iostreams::close_handle);
iostreams::stream<iostreams::file_descriptor_sink> os(fdsink);
// actual interaction with the process
std::string line;
std::getline(is, line);
assert(line == "number?");
std::cout << "sending: " << "5" << std::endl;
os << "5" << std::endl; // RUN GETS STUCK HERE
std::getline(is, line);
assert(line == "6");
}
Очевидно, что я не понимаю логику раковин и источников. Я также попытался использовать один pipe
для раковины и источника, но это не сработало.
Как я могу сделать программу как для чтения, так и для записи из исполняемого проекта?
Я не могу найти пример, в котором ввод и вывод чередуются.
EDIT, чтобы показать рабочий пример с более ранней версией библиотеки
Это как делалось в Boost.Process GSOC2010 (не 0,5, как в вопросе выше) , обратите внимание, что фактическое взаимодействие с программой является таким же, как указано выше.
#include <boost/filesystem.hpp> // quasibug in process GSOC2010 needs to include filesystem BEFORE
#include <boost/process.hpp> // version GSOC2010 (not 0.5)
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
using namespace boost;
int main() {
// boiler plate code
std::vector<std::string> args;
process::context ctx;
ctx.process_name = "askprocess";
ctx.streams[process::stdout_id] = boost::process::behavior::pipe();
ctx.streams[process::stdin_id ] = boost::process::behavior::pipe();
process::child c = create_child("./ask", args, ctx);
process::pistream is(c.get_handle(process::stdout_id));
process::postream os(c.get_handle(process::stdin_id));
// actual interaction with the process
std::string line;
std::getline(is, line);
assert(line == "number?");
std::cout << "sending: " << "5" << std::endl;
os << "5" << std::endl; // RUN GETS STUCK HERE
std::getline(is, line);
assert(line == "6");
}
Улучшенные версии (вы были запутанные копии объектов устройств): [тест .cpp] (http://paste.ubuntu.com/10722864/), [child.cpp] (http://paste.ubuntu.com/10722869/). Он [работает несколько раз] (http://paste.ubuntu.com/10722872/), но я не нашел, как заставить его работать надежно – sehe
Он работает иногда? :(Я просто скопировал ваш код, и он застрял с самого начала (не печатает даже первую строку). Boost 1.55, gcc 4.9.2, (или clang 3.5), Fedora 22. Очень грустно. Еще раз я должен вернуться to Boost.Process 0.3. – alfC
Здесь: ubuntu, boost 1.57, gcc 4.8.2. Теперь вы подразумеваете, что он работает в BP0.3? – sehe