Serguntii
Помогающий
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
Деятель
Команда клуба
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
Спокойный
Администратор
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
Молодой специалист
Offline
|
|
« Ответ #3 : 07-11-2013 06:18 » |
|
Как перехватить stdout в программе которая будет использовать эту dll.
прошу прощения, можно всё-таки уточнить задачу, безотносительно dll или нет. Что у Вас есть, и что Вы хотите достигнуть. Например: "у меня есть программа А, есть программа B, я хочу запускать программу А из программы B, и чтобы в программу B направлялся весь вывод, который программа A выдаёт в стандартный поток вывода"
|
|
|
Записан
|
|
|
|
Serguntii
Помогающий
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
Помогающий
Offline
|
|
« Ответ #5 : 07-11-2013 15:05 » |
|
если ты заменяешь поток вывода на собственный: допустим, пишущий в строковый буфер. Если не затруднит набросайте пример пожалуйста как это сделать, спасибо.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #6 : 07-11-2013 16:28 » |
|
На C++ или в .NET? И я не понимаю роли функции jobfunction - зачем всякие обёртки? Что у Вас есть, и что Вы хотите достигнуть. Присоединяюсь к вопросу. sergeyan, или у тебя есть исходники, в которых много где по разным поводам пишется в stdout, и ты не хочешь всё это переделывать, поэтому пытаешься оформить эти исходники в виде дочернего процесса, вывод которого обрабатывается другим (управляющим) процессом. Или у тебя есть исходники, в которых весь вывод происходит через централизованную функцию типа jobfunction, которую ты можешь переписать как угодно. Тогда ты код оформляешь библиотекой и цепляешь к своей программе. Или у тебя есть исходники, в которых ты готов вручную заменить все вызовы на вызов собственной централизованной функции типа jobfunction. Тогда ты тоже код оформляешь библиотекой и цепляешь к своей программе. Или никто вообще не понимает, что там у тебя есть.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Serguntii
Помогающий
Offline
|
|
« Ответ #7 : 07-11-2013 17:03 » |
|
sergeyan, или у тебя есть исходники, в которых много где по разным поводам пишется в stdout, и ты не хочешь всё это переделывать, поэтому пытаешься оформить эти исходники в виде дочернего процесса, вывод которого обрабатывается другим (управляющим) процессом.
Много исходников от линукс программ не хочется все это переделывать. а тут понадобилось сделать программу под visual studio c#. все впихнул в dll все работает замечательно но вывод был сделан через stdout (
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #8 : 07-11-2013 17:16 » |
|
Если не используются специфичные библиотеки системы, то для C/C++ программ в принципе не должно быть разницы, В винде они компилируются или в Линуксе. А вот если ты хочеш ее интегрировать в другую программу, то зачем тебе лишние сложности?
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #9 : 07-11-2013 17:39 » |
|
Если способ вывода в stdout не централизованный, а код использует стандартную библиотеку C (функцию printf) то проще дочерний процесс использовать.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Serguntii
Помогающий
Offline
|
|
« Ответ #10 : 07-11-2013 17:50 » |
|
то проще дочерний процесс использовать. Как консульное приложение и перехватывать sdtout ? Если не используются специфичные библиотеки системы, то для C/C++ программ в принципе не должно быть разницы, В винде они компилируются или в Линуксе. А вот если ты хочеш ее интегрировать в другую программу, то зачем тебе лишние сложности? Что тогда придумать заново писать?
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #11 : 07-11-2013 18:10 » |
|
sergeyan, Зачем заново? Если код написан правильно, то весь вывод будет происходить практически в одном месте. Тебе нужна именно та часть, которая производит расчеты. Вот ее нужно как-то дописать, чтоб она брала данные из структуры и выдавала рузультат в структуру. А дальше уже намного легче интергрировать код в свою программу и лишний код по выводу на консоль можно выкинуть. Но это если код написан правильно.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #12 : 08-11-2013 06:26 » |
|
sergeyan, есть функция popen() которая позволяет запускать дочерние процессы сразу перехватив их стандартный вывод в виде потока FILE*. Если Вы оставите программы, написанные под Linux в их исходном виде, без всяких dll, то останется только вызывать их через popen() и читать из этого потока, что они Вам выводят.
|
|
|
Записан
|
|
|
|
Serguntii
Помогающий
Offline
|
|
« Ответ #13 : 09-11-2013 07:41 » |
|
Спасибо, все получилось конечно только благодаря вашей помощи )
|
|
|
Записан
|
|
|
|
|