Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.02.2009, 08:40   #1
Zefick
Пользователь
 
Регистрация: 27.05.2008
Сообщений: 14
Вопрос Межпроцессное взаимодействие. Каналы.

Суть в следующем: необходимо наладить взаимодействие консольного шахматного движка и оболочки для него. Движок консольный, оболочка моя и все изменения можно проделать только в неё. Движок запускается оболочкой и его ввод/вывод должен быть перенаправлен в оболочку. Единственный подходящий вариант, насколько я понял, это использование каналов.
По одной из ссылок, которую я нашёл был дан пример такого взаимодействия (http://vsokovikov.narod.ru/New_MSDN_...е есть в MSDN). Только там всё слишком запутанно и не работает. Зачем-то копируются дескрипторы I/O родительского процесса, затем снова восстанавливаются, видимо, чтобы не делать изменений в дочернем. Вот что у меня получилось в моём коде:
Код:
	HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
		hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
		hInputFile, hSaveStdin, hSaveStdout;
	
	SECURITY_ATTRIBUTES sa;

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

	CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, 0);
	SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr);
	DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(),
		&hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
	CloseHandle(hChildStdoutRd);

	hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
	CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa, 0);
	SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd);
	DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), 
		&hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
	CloseHandle(hChildStdinWr);

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	STARTUPINFO si = {sizeof(si)};
	GetStartupInfo(&si);
 
	CreateProcess(_T("Rybka.exe"), NULL, NULL, NULL, TRUE, 
		CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

	SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
	SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
	hInputFile = hSaveStdin;

	char out[10000];
	char * in = "uci";
	DWORD bread;
	Sleep(1000);
	WriteFile(hChildStdinWrDup, in, 100, &bread, NULL);
	Sleep(1000);
	ReadFile(hInputFile, out, 10000, &bread, NULL);
	MessageBoxA(0, out, "uci", 0);

	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
И к тому же консоль после этого не закрывается.

Смотрел еще пример http://www.codenet.ru/progr/bcb/pipes.php. Там, вроде попроще, вот, что у меня получилось:
Код:
	HANDLE newstdin, newstdout, read_stdout, write_stdin;

	SECURITY_ATTRIBUTES sa;

	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	CreatePipe(&read_stdout, &newstdout, &sa, 0);
	CreatePipe(&write_stdin, &newstdin, &sa, 0);
	SetStdHandle(STD_OUTPUT_HANDLE, newstdout);
	SetStdHandle(STD_INPUT_HANDLE, newstdin);

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	STARTUPINFO si = {sizeof(si)};
	GetStartupInfo(&si);

	si.dwFlags = STARTF_USESTDHANDLES; //***
	si.hStdOutput = newstdout;
	si.hStdError = newstdout;
	si.hStdInput = newstdin;
 
	CreateProcess(_T("Rybka.exe"), NULL, NULL, NULL, TRUE, 
		CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
Далее такое-же чтение и запись. Тут вроблема в том, что если в коде присутствует отмеченная строка (si.dwFlags = STARTF_USESTDHANDLES; ), то консоль сразу после создания закрывается, а если нет, то никокого взаимодействия опять не происходит.

Подскажите, как правильно делать то, что я задумал. И должно ли в консоли высвечиваться то, что передаёт ей родительский процесс и что она выдаёт?
Zefick вне форума Ответить с цитированием
Старый 27.02.2009, 21:08   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Это примеры создания анонимного пайпа с перенаправлением ввода/вывода в/из него. Для межпроцессного взаимодействия, имхо, лучше двунаправленный именованный пайп (CreateNamedPipe). В msdn есть пример многопоточного сервера.
Somebody вне форума Ответить с цитированием
Старый 01.03.2009, 10:13   #3
Zefick
Пользователь
 
Регистрация: 27.05.2008
Сообщений: 14
По умолчанию

Мне не подходят именованные пайпы, так как код клиента не доступен.
Необходимо всего-лишь запустить один процесс из другого и перенаправить ввод и ввывод.
Насколько я понял, перенаправления в примере не происходит. Клиент просто пишет в пайп, дескриптор которого ему передают, а его собственные потоки ввода/вывода не используются.
Zefick вне форума Ответить с цитированием
Старый 02.03.2009, 20:48   #4
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Creating a Child Process with Redirected Input and Output
Somebody вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Межпроцессное взаимодействие ilham Win Api 5 16.12.2008 13:01
Взаимодействие flash и C#? mrakaziabra Общие вопросы .NET 3 16.07.2008 07:16
взаимодействие с QIP Toxa Общие вопросы Delphi 5 20.06.2008 19:39
Взаимодействие с twain jonbc Win Api 4 06.04.2007 23:35