Кроссплатформенное перенаправление стандартного ввода и вывода порожденного процесса на родном C / C ++ (редактирование с решением)
У меня есть строковая команда I 'Я хотел бы выполнять асинхронно во время записи на вход и чтения выходных данных. Звучит легко, верно, дьявол в кроссплатформенности. Я'm ориентированы как на MSVC / Win32, так и на gcc / Linux и, очевидно, хотят написать минимальный объем кода для конкретной платформы. Мой гугл-фу подвел меня, я получаю слишком много шума для своих запросов, поэтому я начал с того, что знаю.
POPEN - красиво и легко, возвращает FILE *, который легко использовать везде. Но здесь'с чемMSDN должен сказать о _popen:
При использовании в программе Windows функция _popen возвращает недопустимый указатель файла, из-за которого программа перестает отвечать на запросы неопределенно долго. _popen работает правильно в консольном приложении. Чтобы создать приложение Windows, которое перенаправляет ввод и вывод, см. Создание дочернего процесса с перенаправленным вводом и выводом в SDK платформы.
и поэтому попен не может быть и речи (правка: потому что яМне бы хотелось, чтобы мой код работал в приложении с графическим интерфейсом). Способ Windows сделать это, на мой взгляд, довольно уродлив и многословен. Я мог бы жить с платформенным кодом вызова, но яЯ хотел бы, чтобы хотя бы код ввода-вывода был таким же. Здесь, однако, я ударил стену между WinAPIHANDLE
с и сFILE*
, а такжеint
дескриптор файла. Есть ли способпреобразоватьHANDLE
вFILE*
или жеint
фд или наоборот? (Google снова подвел меня в этом вопросе, все ключевые слова, которые я пробовал, чрезмерно используются)
Есть ли лучший способ сделать все это с небольшим кодом для конкретной платформы?
О внешних библиотеках не может быть и речи, однако поддержка зависимостей - это боль, особенно на нескольких платформах, поэтому яЯ хотел бы уменьшить зависимости. Я не'Такую библиотеку тоже не найти в boost.
Просто для записи, что сработало для меня в конце концов. В Windows / MSVC, +CreatePipe()
CreateProcess()
как изложеноВот, с помощью_open_osfhandle()
с последующим_fdopen()
получитьFILE*
к процессу ввода и вывода. На Linux / GCC, ничего нового здесь, созданиеpipe()
s;fork()
затемdup2()
трубы; ;exec()
fdopen()
на соответствующих файловых дескрипторов. Таким образом, только процессный код процесса зависит от платформы (что нормально, как в Windows I 'хотел бы контролировать дополнительныеSTARTUPINFO
параметры), запись ввода и чтение вывода осуществляется через стандартныйFILE*
и связанные функции.