Я пытаюсь получить данные от дочернего процесса через анонимный канал в Windows. Я знаю, как это сделать, используя стандартные потоки ввода / вывода, но они используются для других целей. Я также знаю, как сделать это в Linux или OSX с помощью fork()
, pipe()
а также execv()
,
В Windows вы можете создать канал с CreatePipe()
и сделать один конец не наследуется с SetHandleInformation()
, Тогда для stdout и stderr вы можете передать STARTUPINFO
, с hStdOutput
или же hStdError
установлен в CreateProcess()
передать другой конец ребенку. После звонка CreateProcess()
родитель наиболее близко это ручка к дочернему концу трубы. Это все подробно объясняется в Создание дочернего процесса с перенаправленным вводом и выводом на MSDN. Тем не менее, я не нашел способ передать HANDLE
, кроме как через stderr, stdout или stdin, ребенку.
Я пытался преобразовать HANDLE
в строку с чем-то вроде этого:
std::ostringstream str;
str << hex << "0x" << handle;
std::string handleArg = str.str();
А затем передать его в качестве аргумента командной строки и преобразовать его обратно в HANDLE
, который просто void *
в дочернем процессе. Хотя дочерний процесс явно наследует канал HANDLE
фактическая стоимость HANDLE
должен отличаться от родительского, потому что его передача не работает.
Я знаю, что я могу использовать именованный канал, чтобы сделать это, но, кажется, должно быть возможно сделать это с анонимными каналами.
Так как я могу передать трубу HANDLE
дочернему процессу в Windows?
Update1: Пример кода в эта статья MSDN кажется, указывает на то, что, по крайней мере с дескрипторами сокетов, вы можете передать их в виде строки дочернему элементу.
Update2: Оказывается, я допустил ошибку. Смотрите мой ответ ниже.
Оказывается, ты Можно передать HANDLE
дочернему процессу в качестве аргумента командной строки, преобразовав его в строку, а затем, в дочернем процессе, обратно в HANDLE
(который просто void *
). Пример кода с использованием HANDLE
к розетке можно нашел здесь.
Чтобы сделать эту работу, вы должны убедиться, что вы следуете Создание дочернего процесса с перенаправленным вводом и выводом тесно. Важно, чтобы вы закрыли конец канала дочернего процесса после вызова CreateProcess()
и получить все настройки наследования правильно.
Обратите внимание, я пытался передать HANDLE
как строка в командной строке раньше, но я делал это неправильно. Моя ошибка была в прохождении HANDLE
как int
в boost::iostreams::file_descriptor()
что заставило его рассматривать его как файловый дескриптор вместо Windows HANDLE
,