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

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

ru
Offline Offline

« : 06-11-2013 18:31 » 

Собрал старые исходники на си в библиотеку dll ,скомпилировал в visual studio 2010 c++ net  для внешнего вызова поместил все функции в класс.
Код:
FILE* outfl;
namespace dllmy{
public r: ref class dllclas
{
public dllclas()
{
outfl = stdout;
}//constr
 
int jobfunctionZZ()
{
jobfunction();
}
}



Старые исходники
Код:
jobfunction()
{
fprintf(outfl,"%s",line);
}

Как перехватить stdout в программе которая будет использовать эту dll.
Код:
using dllmy;

dllclas dll = new dllclas();

dll.jobfunctionZZ()





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

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

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

sergeyan, нет, в стандартной библиотеке C ты можешь работать только с дескрипторами потоков FILE из stdio.h или (на более низком уровне) дескрипторами из io.h. Тут вариантов почти нет: открываешь собственный файл, туда пишешь, потом из него читаешь. Это не конвейер. Конвейер можно сделать в UNIX-системах, создав файл типа pipe (они для того и нужны, что в UNIX подобные перенаправления стандартных потоков - типовой приём). Однако если вместо fprintf использовать sprintf и писать в строковый буфер, из которого потом читать, то кое-что становится возможным, но события записи не отследить.

В стандартной библиотеке C++ ты можешь работать с объектами потоков - вот тут появляется возможность перехвата, если ты заменяешь поток вывода на собственный: допустим, пишущий в строковый буфер. Причём появляются возможности отслеживать события операций над буфером, добавив в методы обращения соответствующие средства сигнализации.

В WinAPI тоже работа идёт по дескрипторам, однако дескрипторами могут быть не только файлы на диске, но и файлы в памяти (memory mapped files), и именованные каналы (named pipes). Поэтому возможности организации конвейера расширяются.
Записан

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

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


« Ответ #2 : 06-11-2013 22:02 » 

sergeyan, Ты задаеш вопросы в принципе около одной и той же темы. Я вот не пойму, почему нельзя твою программу на с не сделать ввиде "данные -> получение расчетов. Следушая порция данных. И все выводы на консоль просто офрмить как возврат функции минуя саму консоль.
Код:
struct dataIn {
//структура  c данными
}

struct dataOut {
//структура  c данными
}

dateOut *solvedProblem(const Datein& val) {
//Сами расчеты
}
Промежуточные данные которые будут воздействовать на дальнейшие расчеты можно хранить в static полях внутри функции. Уже в самом шарпе создаещ поток, который будет дергать функцию из Dll и делать все расчеты.
« Последнее редактирование: 06-11-2013 22:07 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
darkelf
Молодой специалист

ua
Offline Offline

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

Как перехватить stdout в программе которая будет использовать эту dll.
прошу прощения, можно всё-таки уточнить задачу, безотносительно dll или нет. Что у Вас есть, и что Вы хотите достигнуть. Например: "у меня есть программа А, есть программа B, я хочу запускать программу А из программы B, и чтобы в программу B направлялся весь вывод, который программа A выдаёт в стандартный поток вывода"
Записан
Serguntii
Помогающий

ru
Offline Offline

« Ответ #4 : 07-11-2013 09:55 » 

Цитата
В стандартной библиотеке C++ ты можешь работать с объектами потоков - вот тут появляется возможность перехвата, если ты заменяешь поток вывода на собственный: допустим, пишущий в строковый буфер. Причём появляются возможности отслеживать события операций над буфером, добавив в методы обращения соответствующие средства сигнализации.
Вот этот решение подошло бы в самый раз.  Собираю код на с++ и классы net тоже используються.
Заменяю функции fprintf(fileout,"%s",line);  на другую функцию которая будет писать в String^?
Код который в длл, в этой длл всего один этот класс, все старые функции просто подключены через #include "old.h"  в файле stdfax.h.
Код:
FILE* outfl; //взамен этого нужно добавить переменную String^ в этом классе?
namespace dllmy{
public r: ref class dllclas
{
String^buferstr;
public dllclas()
{
outfl = stdout;
buferstr = "";
}//constr
 
int jobfunctionZZ()
{
       jobfunction(); //эта функция описана в old.h реализована в old.c

}//jobfunctionZZ для внешнего вызова из этой длл.

}//end class

Теперь когда когда внешняя программа вызовет метод jobfunctionZZ() он вызовет функцию jobfunction(); Результат ее работы должен записать fprintf но мы его заменим. Тут я не понимаю как записать в buferstr ?






Записан
Serguntii
Помогающий

ru
Offline Offline

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

Цитата
если ты заменяешь поток вывода на собственный: допустим, пишущий в строковый буфер.
Если не затруднит набросайте пример пожалуйста как это сделать, спасибо.
Записан
Dimka
Деятель
Команда клуба

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

« Ответ #6 : 07-11-2013 16:28 » 

На C++ или в .NET? И я не понимаю роли функции jobfunction - зачем всякие обёртки?

Цитата: darkelf
Что у Вас есть, и что Вы хотите достигнуть.
Присоединяюсь к вопросу.

sergeyan, или у тебя есть исходники, в которых много где по разным поводам пишется в stdout, и ты не хочешь всё это переделывать, поэтому пытаешься оформить эти исходники в виде дочернего процесса, вывод которого обрабатывается другим (управляющим) процессом.

Или у тебя есть исходники, в которых весь вывод происходит через централизованную функцию типа jobfunction, которую ты можешь переписать как угодно. Тогда ты код оформляешь библиотекой и цепляешь к своей программе.

Или у тебя есть исходники, в которых ты готов вручную заменить все вызовы на вызов собственной централизованной функции типа jobfunction. Тогда ты тоже код оформляешь библиотекой и цепляешь к своей программе.

Или никто вообще не понимает, что там у тебя есть.
Записан

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

ru
Offline Offline

« Ответ #7 : 07-11-2013 17:03 » 

Цитата
sergeyan, или у тебя есть исходники, в которых много где по разным поводам пишется в stdout, и ты не хочешь всё это переделывать, поэтому пытаешься оформить эти исходники в виде дочернего процесса, вывод которого обрабатывается другим (управляющим) процессом.

Много исходников от линукс программ не хочется все это переделывать. а тут понадобилось сделать программу под visual studio c#. все впихнул в dll все работает замечательно но вывод был сделан через stdout (
Записан
Finch
Спокойный
Администратор

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


« Ответ #8 : 07-11-2013 17:16 » 

Если не используются специфичные библиотеки системы, то для C/C++ программ в принципе не должно быть разницы, В винде они компилируются или в Линуксе. А вот если ты хочеш ее интегрировать в другую программу, то зачем тебе лишние сложности?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dimka
Деятель
Команда клуба

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

« Ответ #9 : 07-11-2013 17:39 » 

Если способ вывода в stdout не централизованный, а код использует стандартную библиотеку C (функцию printf) то проще дочерний процесс использовать.
Записан

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

ru
Offline Offline

« Ответ #10 : 07-11-2013 17:50 » 

Цитата
то проще дочерний процесс использовать.
Как консульное приложение и перехватывать sdtout ?
Цитата
Если не используются специфичные библиотеки системы, то для C/C++ программ в принципе не должно быть разницы, В винде они компилируются или в Линуксе. А вот если ты хочеш ее интегрировать в другую программу, то зачем тебе лишние сложности?
Что тогда придумать заново писать?
Записан
Finch
Спокойный
Администратор

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


« Ответ #11 : 07-11-2013 18:10 » new

sergeyan, Зачем заново? Если код написан правильно, то весь вывод будет происходить практически в одном месте. Тебе нужна именно та часть, которая производит расчеты. Вот ее нужно как-то дописать, чтоб она брала данные из структуры и выдавала рузультат в структуру. А дальше уже намного легче интергрировать код в свою программу и лишний код по выводу на консоль можно выкинуть. Но это если код написан правильно.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #12 : 08-11-2013 06:26 » 

sergeyan, есть функция popen() которая позволяет запускать дочерние процессы сразу перехватив их стандартный вывод в виде потока FILE*. Если Вы оставите программы, написанные под Linux в их исходном виде, без всяких dll, то останется только вызывать их через popen() и читать из этого потока, что они Вам выводят.
Записан
Serguntii
Помогающий

ru
Offline Offline

« Ответ #13 : 09-11-2013 07:41 » 

Спасибо, все получилось конечно только благодаря вашей помощи )
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines