Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: интерфейс между программами  (Прочитано 19418 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Serguntii
Помогающий

ru
Offline Offline

« : 02-11-2013 07:10 » 

Нужна  помощь. Есть старенькая программа консульная, ее задача считать, она написана на с, работает так: значение получает gets а результат выдает print. Возникла задача не переделываю эту программу добавить туда код что бы можно было передавать значения из программы C# net и как-то перенаправить print что бы результат приходил в программу C#.
« Последнее редактирование: 02-11-2013 07:15 от sergeyan » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 02-11-2013 07:25 » 

Ввод можно сделать ввиде параметров запуска. Если слишком много ввода (больще чем 128 символов), тогда можно передавать через файл. А вывод просто читать с консоли. Или сбрасывать в файл. Вывод не нужно переписывать. Даже сброс в файл можно добиться средствами самой OS. После строчки вызова программы добавить >Имя_файла .
Например
math 1234567890 >temp
« Последнее редактирование: 02-11-2013 07:30 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #2 : 02-11-2013 07:36 » 

Спасибо за ответ. При запуске получиться  передача только один раз, если правильно понял. А нужно пока работает программа C# работает и эта консульная . программа на C# должна ей постоянно передавать аргументы а та ей возвращать результаты.

Добавлено через 1 минуту и 45 секунд:
Хорошо бы еще спрятать консуль но это не так важно сейчас.
« Последнее редактирование: 02-11-2013 07:38 от sergeyan » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 02-11-2013 08:57 » 

Из C# вызывать программу на С, перехватив потоки ввода/вывода и замкнув на C#-клиента.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #4 : 02-11-2013 09:04 » 

Красивые сказано ) а как это сделать?
Код:

Process process;
        private void Form1_Load(object sender, EventArgs e)
        {
            process = new Process();
            process.StartInfo.FileName = @"C:\old.exe";
            process.StartInfo.WorkingDirectory = "c:\temp";
            process.Start();
        }
 
 
        private void button1_Click(object sender, EventArgs e)
        {
 
             process ? =textBox1.Text;
             process ? =textBox2.Text;
 
        }

старая программа


main (int argc, char ** argv)
{
    int status;
    int choice;
    char buffer[150];
.......
.....
 
    for(; ;)
    {
 
    как-то получить что ушло из texbox1-2 или поймать то событие с теми значениями из textbox ума не приложу как это сделать(
     gets(buffer);
 
 
    }
...
....
...
}




Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 02-11-2013 10:06 » 

У любой (кроме демонов) консольной программы есть три дескриптора файлов по умолчанию stdin, stdout и stderr. stdin поток ввода, stdout поток вывода и stderr поток вывода ошибок. Следовательно в C# программе нужно копать в эту сторону. Т.е. искать путь переписывания этих потоков на себя.

Добавлено через 15 минут и 50 секунд:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx
Посмотри свойства StandardOutput,  StandardInput. Там есть примеры кода.
« Последнее редактирование: 02-11-2013 10:26 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #6 : 02-11-2013 12:45 » 

Почти то что нужно ). Еще такая мысль появилась собрать dll  с ++ из этих старых исходников, вроде должно получиться  , но как сделать что бы функции из этой dll вызывали функции в C# можно что то придумать? Что то типа события или делегата тоже у меня тупик (
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 02-11-2013 17:47 » 

Можно. Через C++.NET. Делегаты с событиями тут ни при чём.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #8 : 02-11-2013 20:57 » 

Понятно думаю сейчас над этим. Возникла еще одна мысль можно как-то отслеживать событие в отдельном  потоке sdout stderr на с++  в dll и как в них что то появиться вызвать мою функцию?


Thread tt = gcnew Thread(tasg)

task()
{
for(;Ага{
sprintf(buff)
myfun(buff);
}


}



Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 03-11-2013 07:45 » 

Можно много чего. Главный вопрос, каков смысл этих действий?

P.S. для оформления кода используй теги

[code]
for(;;) {
}
[/code]
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #10 : 05-11-2013 06:50 » 

Виноват. Нужно для того что бы когда появиться что то в stdout вызвать мою функцию. Как проверить наличие данных в stdout?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #11 : 05-11-2013 07:43 » 

sergeyan, уже нечто подобное разбирали, например здесь:
https://forum.shelek.ru/index.php/topic,29591.0.html
Записан
Serguntii
Помогающий

ru
Offline Offline

« Ответ #12 : 05-11-2013 08:31 » 

Сейчас посмотрю.Все же хочется сделать проверку sdout в потоке. Cделал не знаю насколько правильно?
Код:



newThread = gcnew Thread( gcnew ThreadStart(this, &pipi::ThreadProc ) );
newThread->Start();



//-------------------------------------------------------//
public: void ThreadProc()
  {
  for(;;)
  {

 if(stdout!=NULL)
 {

 SetDataToSdtdout(Convert::ToString(stdout));
 fflush(stdout);

 }//if

  }//for
  }
//-------------------------------------------------------//
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 05-11-2013 11:12 » 

sergeyan, ты либо не понял того, что по ссылке в другой теме было написано, либо вовсе не улавливаешь асинхронности.

Поток представляет собой элемент, с состоянием которого связывается объект синхронизации. Таким образом, разовая асинхронная задача - это:
1) Висеть и ждать, пока не изменится состояние потока.
2) Если не достигнут конец потока, то
2.1) Обработать эту порцию данных - что-то сделать.
2.2) Запустить новую асинхронную задачу.

Это может решаться при помощи асинхронных задач, реализованных в виде "зелёных нитей" (green threads) на базе пула нитей процесса (system threads pool). Классы, описывающие асинхронную модель работы процесса находятся в пространстве имён System.Threading.Tasks (актуально для .NET 4.0 и выше).

Задача может решаться при помощи цикла внутри одной асинхронной задачи, запущенной любым способом (в том числе в созданной нити).

Однако в обоих случаях алгоритм должен быть таким, как описано выше, чтобы:
1) исключить случай зависания нити (и вместе с нею всего процесса, если это не background-нить), если нить будет ждать синхронного чтения из потока.
2) исключить случай холостого хода нити, если нить будет крутить цикл с опросом состояния потока без синхронного чтения.

В стандартной библиотеке C/C++ потоки не являются объектами синхронизации нитей. Такие возможности есть либо в WinAPI, либо в .NET.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #14 : 05-11-2013 11:57 » 

Я действительно не все понимаю, не очень давно начал программировать. А тот пример что я написал не правильный ?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 05-11-2013 12:28 » 

sergeyan, там мысль правильная, но нюансы - нет.

А вот о чём по ссылке шла речь:
Код: (C#)
Process process = new Process();
process.StartInfo.FileName = @"mypath\child.exe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived +=
    (object sender, DataReceivedEventArgs a) =>
    {
        // Вызывается асинхронно на каждую прочитанную строчку из стандартного вывода дочернего процесса.
        // Прочитанные строчки выводятся в стандартный вывод текущего потока.
        Console.Write(a.Data);
    };
process.Start();
// Начало асинхронного чтения - управление вспомогательными нитями происходит автоматически.
process.BeginOutputReadLine();
// Основная нить спит здесь до окончания работы дочернего процесса
process.WaitForExit();
В данном случае не нужно вручную управлять потоками и отлаживать глюки при их синхронизации. Просто используются имеющиеся возможности.
« Последнее редактирование: 05-11-2013 12:32 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #16 : 05-11-2013 14:14 » 

Спасибо большое за подробное разъяснение.

Добавлено через 20 часов, 10 минут и 47 секунд:
Код:
Process process = new Process();
process.StartInfo.FileName = @"mypath\child.exe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived +=
    (object sender, DataReceivedEventArgs a) =>
    {
        // Вызывается асинхронно на каждую прочитанную строчку из стандартного вывода дочернего процесса.
        // Прочитанные строчки выводятся в стандартный вывод текущего потока.
        Console.Write(a.Data);
    };
process.Start();
// Начало асинхронного чтения - управление вспомогательными нитями происходит автоматически.
process.BeginOutputReadLine();
// Основная нить спит здесь до окончания работы дочернего процесса
process.WaitForExit();

Еще одна мысль а если в dll этот код использовать?
Код:
Process process = GetCurrentProcess();
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived +=
    (object sender, DataReceivedEventArgs a) =>
    {
        // Вызывается асинхронно на каждую прочитанную строчку из стандартного вывода дочернего процесса.
        // Прочитанные строчки выводятся в стандартный вывод текущего потока.
        Console.Write(a.Data);
    };
process.Start();
// Начало асинхронного чтения - управление вспомогательными нитями происходит автоматически.
process.BeginOutputReadLine();
// Основная нить спит здесь до окончания работы дочернего процесса
process.WaitForExit();





« Последнее редактирование: 06-11-2013 10:25 от sergeyan » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #17 : 06-11-2013 10:39 » 

Еще одна мысль а если в dll этот код использовать?
Прошу прощения, не знаток C#, но мне кажется, что код будет идентичный тому, который привёл Dimka - имхо не надо заменять new Process() на GetCurrentProcess().
Записан
Serguntii
Помогающий

ru
Offline Offline

« Ответ #18 : 06-11-2013 11:01 » 

Код:
Прошу прощения, не знаток C#, но мне кажется, что код будет идентичный тому, который привёл Dimka - имхо не надо заменять new Process() на GetCurrentProcess().
Этот код будет в длл, а конструктор с этим кодом вызывает уже запущенный процесс. То длл относится к процессу который вызвал конструктор из длл . Если правильно понимаю?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #19 : 06-11-2013 12:41 » 

Этот код будет в длл, а конструктор с этим кодом вызывает уже запущенный процесс. То длл относится к процессу который вызвал конструктор из длл . Если правильно понимаю?
прошу прощения, не совсем понял, как можно запустить уже запущенный процесс? он вроде как уже запущен..
Записан
Serguntii
Помогающий

ru
Offline Offline

« Ответ #20 : 06-11-2013 13:27 » 

А если его как-то остановить вначале а потом опять запустить  получиться?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #21 : 06-11-2013 15:15 » 

к сожалению совсем ничего не понял.. мне кажется, что хоть в dll, хоть вне его - в коде основного процесса, вызывающий код должен быть одинаков - создать объект, описывающий новый процесс и запустить его..
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 06-11-2013 17:04 » 

sergeyan, это бред какой-то. Процесс - это контекст (т.е. кусок памяти) в котором хранятся данные и код, который выполняет процессор. Если процесс сам себя остановит (а это возможно разными способами), то алгоритм перестанет выполняться, и, соответственно, та его часть, что отвечает за "запуск" не будет выполнена: её выполнять-то должен процесс, которого уже нет.

Никакого GetCurrentProcess. И dll тут ни при чём вовсе.

Если все эти извращения нацелены на перехват стандартного потока вывода самого процесса (текущего), то это вовсе не так делается. Пример был посвящён именно связке двух рабочих процессов в конвейер.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Serguntii
Помогающий

ru
Offline Offline

« Ответ #23 : 06-11-2013 18:02 » new

Цитата
Пример был посвящён именно связке двух рабочих процессов в конвейер.
Спасибо, вначале была цель связать два процесса ,понял как это сделать благодаря вашей помощи. в 15 сообщении.
« Последнее редактирование: 06-11-2013 18:04 от sergeyan » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines