C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Pipes, Проблема с входным потоком
Schumi
Отправлено: 07.04.2004, 18:06


Машинист паровоза

Группа: Участник
Сообщений: 206



У меня есть две проги: Win и Dos(command promt). Выходной поток Dos я считываю и вывожу в Win в Memo. А с входным есть проблема: когда я отправляю в входной поток char (типа нажали клавишу),она начинает в выходной выдавать непрерывный поток символов.
Может не заморачиваться с входным потоком,а использовать типа:PostMessage(pi.hProcess,WM_CHAR,symb, 0);.
Может что-то я напутал.Подсобите.
CODE

#define bzero(a) memset(a,0,sizeof(a))
const Len=5120;
char buf[Len+1];
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
PROCESS_INFORMATION pi;
HANDLE newstdin,newstdout,read_stdout,write_stdin;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true;
CreatePipe(&newstdin,&write_stdin,0,0)
CreatePipe(&read_stdout,&newstdout,0,0))
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.hStdOutput = newstdout;
si.hStdError = newstdout;
si.hStdInput = newstdin;
//Для примера Command="time"
CreateProcess(NULL,Command.c_str(),NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pilong unsigned exit=0;
unsigned long bread;
unsigned long avail;
bzero(buf);
for(;;)
 {
GetExitCodeProcess(pi.hProcess,&exit);
Application->ProcessMessages();
if (exit!=STILL_ACTIVE)
   break;
PeekNamedPipe(read_stdout,buf,Len,&bread,&avail,NULL);
if (bread!= 0)
   {
    bzero(buf);
    if (avail > Len)
        {
         while (bread >= Len)
           {            
            ReadFile(read_stdout,buf,Len,&bread,NULL);            
            bzero(buf);
           }
        }
         else ReadFile(read_stdout,buf,Len,&bread,NULL);
  }
//char KeyFromClient — код нажатой клавиши
if (KeyFromClient!=0)
   {
     bzero(buf);
     *buf=KeyFromClient;      
     WriteFile(write_stdin,buf,1,&bread,NULL);      
     if (*buf=='\r')
      {
       *buf='\n';
       WriteFile(write_stdin,buf,1,&bread,NULL);
       KeyFromClient=0;
      }
   }
 }
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
klen
Отправлено: 08.04.2004, 00:14


Машинист паровоза

Группа: Участник
Сообщений: 239



Видиш ли друг мой. Весь пикус в том что так работает если запускаемый процесс есть суть 32 битный консольный(например всеми нами любимый bcc32.exe который вывод в окно былдера дает во время компиляции проекта), а вот досовские программы хоть и компилится могут с тогоже исходника — есть совсем иное. Для досовской программы (у нее и формат бинарника иной) запускается виртуальная дос машина( я так думаю что это нечто как интерпретатор бинарного дос кода). Вот тут и начинается все самое интересное. Работа 16 битных приложений под этой VDM не документирована, описания я не нашел.
Во всяком случае там точно не каналы используяются как в 32 консольных приложениях. Я долго патался понять как работает command.exe в 95-98 и cmd.exe в w2k\XP ....... к сожалению нет их исходников и нет у меня отладочной версии виндов. Есть идея использовать cmd.exe как прокладку между 16 биным приложением и вызывающим на диалог 32 битным.

Если ктото знает как решить этот вопрос, напишите.
Мне изза этой хренатени пришлось написать свой транслятор ассемблера для КР1878ВЕ1. Получился снежный ком, который щас уже на лавину смахивает

Я могу ошибаться

Отредактировано klen — 08/04/2004, 01:18
Schumi
Отправлено: 08.04.2004, 19:59


Машинист паровоза

Группа: Участник
Сообщений: 206



Полтергейтс какой-то.На следующий день всё заработало.
А по поводу командной строки я сделал так: просто сделал свою маленькую консольную прогу с единственной командой system(argv[1]).
После этого стало всё нормально.А до этого,действительно,не Win32 никак не хотели пускаться

Вернуться в Вопросы программирования в C++Builder