Здравствуйте, dosik, Вы писали:
D>Добрый день.
D>Осваиваюсь в *nix (ранее писал только под Windows) системах. D>Возникла следующая задача: необходимо выполнить из своей программы внешнюю программу таким образом, чтобы в ее поток ввода передать ей некие значения, а результат ее работы получить из ее потока вывода и отобразить результаты внутри своей программы. D>С начала смотрел в сторону exec*, но там немного не то. D>Язык — С++. D>Заранее благодарен.
1. Создаёте два (или три, если нужен stderr) пайпа вызовом pipe().
2. Делаете вызов fork();
3. В дочерней программе делаете dup2(stdinpipe[0], 0), т.е. стандартный ввод заменяете этим пайпом. То же самое делаете со стандартным выводом (1), если нужно — со стандартным выводом ошибок. Закрываете все дескрипторы pipe. Не перепутайте порядок дескрипторов, с stdin ваша программа будет читать, в stdout писать.
4. В дочерней программе делаете exec в нужную вам программу.
5. В родительской программе закрываете те дескрипторы pipe, которые используются дочерней программой.
В принципе всё. В родительской программе пишете в оставшиеся дескрипторы, читаете из них и тд.
Главное вдумчиво почитать man-ы по всем используемым функциям. Ничего сложного, на самом деле.
Раз у вас C++, можете навернуть абстракций над всем этим или какой-нибудь, прости господи, буст заюзать. Там наверное всё это под капотом спрятано. Но вообще это делается вот так.
Осваиваюсь в *nix (ранее писал только под Windows) системах.
Возникла следующая задача: необходимо выполнить из своей программы внешнюю программу таким образом, чтобы в ее поток ввода передать ей некие значения, а результат ее работы получить из ее потока вывода и отобразить результаты внутри своей программы.
С начала смотрел в сторону exec*, но там немного не то.
Язык — С++.
Заранее благодарен.
Re: Выполнить приложение. Параметры в поток ввода, результат из потока вывода
Здравствуйте, dosik, Вы писали:
D>Добрый день.
D>Осваиваюсь в *nix (ранее писал только под Windows) системах. D>Возникла следующая задача: необходимо выполнить из своей программы внешнюю программу таким образом, чтобы в ее поток ввода передать ей некие значения, а результат ее работы получить из ее потока вывода и отобразить результаты внутри своей программы. D>С начала смотрел в сторону exec*, но там немного не то. D>Язык — С++. D>Заранее благодарен.
Для одностороннего общения можно было бы использовать popen. Для двустороннего придется писать самому.
google pipe/fork/dup2/exec
Это именованные каналы. В таком случае мне проще сокетами сделать. Мне же нужно через потоки вводы/вывода. Одну порцию отдать и одну порцию забрать. Что-то типа:
Здравствуйте, dosik, Вы писали:
D>Это именованные каналы. В таком случае мне проще сокетами сделать. Мне же нужно через потоки вводы/вывода. Одну порцию отдать и одну порцию забрать. Что-то типа: >> cat somefile | ./someexec | ./myapp D>Ну очень грубо, просто перенаправить потоки.
Это не именованные каналы, это именно перенаправление потоков. Читай внимательнее.
Re: Выполнить приложение. Параметры в поток ввода, результат из потока вывода
Здравствуйте, dosik, Вы писали:
D>Возникла следующая задача: необходимо выполнить из своей программы внешнюю программу таким образом, чтобы в ее поток ввода передать ей некие значения, а результат ее работы получить из ее потока вывода и отобразить результаты внутри своей программы. D>С начала смотрел в сторону exec*, но там немного не то.
Здравствуйте, vsb, Вы писали:
vsb>В принципе всё. В родительской программе пишете в оставшиеся дескрипторы, читаете из них и тд.
Если ввод длинный и может привести к раннему выводу, то придётся как-то позаботится о дед-локе. Либо какой-нибудь select запользовать, либо ещё один форк для вкачивания ввода, либо отдельный поток. По вкусу
Re: Выполнить приложение. Параметры в поток ввода, результат из потока вывода
Всем огромное спасибо за помощь. Общее направление мне понятно. Дальше буду развивать и думать. popen() + fork() + exec() конечно долговато при условии многоразового одновременного выполнения. Буду думать. Спасибо!
Re: Выполнить приложение. Параметры в поток ввода, результат
Здравствуйте, dosik, Вы писали:
D>Добрый день.
D>Осваиваюсь в *nix (ранее писал только под Windows) системах. D>Возникла следующая задача: необходимо выполнить из своей программы внешнюю программу таким образом, чтобы в ее поток ввода передать ей некие значения, а результат ее работы получить из ее потока вывода и отобразить результаты внутри своей программы. D>С начала смотрел в сторону exec*, но там немного не то. D>Язык — С++. D>Заранее благодарен.
Есть готовое решение — libexecstream — позволяет запускать приложения и предоставляет их ввод/вывод в виде стандартных iostream потоков.
Библиотека несколько старовата, но вполне рабочая. И никакого ковыряния в сишном посиксе.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Здравствуйте, v_andal, Вы писали:
vsb>>В принципе всё. В родительской программе пишете в оставшиеся дескрипторы, читаете из них и тд.
_>Если ввод длинный и может привести к раннему выводу, то придётся как-то позаботится о дед-локе. Либо какой-нибудь select запользовать, либо ещё один форк для вкачивания ввода, либо отдельный поток. По вкусу
Если нам не интересен вывод дочерней программы, можно его перенаправить в /dev/null. Если интересен — да, надо помнить, что буферы в pipe ограниченного размера.