Переопределение stdout / cout
От: e-Inventor Россия  
Дата: 14.11.08 08:59
Оценка:
Здравствуйте

у меня следующая проблема... есть некий класс, у которого есть метод print()
исторически так сложилось, что внутри этого метода используется printf()
который пишет в stdout и менять это нельзя

у меня GUI морда, которая использует этот класс. Мне надо получить
в какую-нибудь переменную вывод этого метода...

пробовал вот таким способом:

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
    ios::sync_with_stdio(true);
    streambuf* cout_buf = cout.rdbuf();
    stringbuf my_buf;
    cout.rdbuf(&my_buf);

    cout << "Hello1" << endl;    
    printf( "Hello2\n" );

    cout.rdbuf( cout_buf );
    
    return 0;
}


но при этом Hello2 не попадает в my_buf (
есть вариант сделать FILE f* = freopen( "text_file.txt", "wt", stdout)
тогда вывод всех printf() пойдет в файл... а после его прочитать..
но как-то это мне не нравится

неужели нельзя перехватить вывод printf() минуя файл?

помогите советом, плиз!
Re: Переопределение stdout / cout
От: TheBeard Россия  
Дата: 14.11.08 09:11
Оценка:
EI>у меня следующая проблема... есть некий класс, у которого есть метод print()
EI>исторически так сложилось, что внутри этого метода используется printf()
EI>который пишет в stdout и менять это нельзя

EI>у меня GUI морда, которая использует этот класс. Мне надо получить

EI>в какую-нибудь переменную вывод этого метода...

EI>пробовал вот таким способом:


printf() -- это стадартная библиотека C, поэтому он ничего не знает о cout из стадартной библиотеки C++ (он выводит не через cout).

Все, что приходит в голову -- запускать дочерний процесс, который будет просто копировать из stdin в stdout. Подключать его ввод к stdtout Вашего процесса и перехватывать его вывод. Если все это в Windows, посмотрите документацию на CreateProcess().
Re: Переопределение stdout / cout
От: zaufi Земля  
Дата: 14.11.08 13:21
Оценка:
если все это в linux то можно написать динамическую нанобиблиотечку которая проста переопределяет функцию printf и грузить ее LD_PRELOADом
в переопределенной функции можешь писать куда захочешь
Re: Переопределение stdout / cout
От: Аноним  
Дата: 14.11.08 14:09
Оценка:
Здравствуйте, e-Inventor, Вы писали:

EI>Здравствуйте


EI>у меня GUI морда, которая использует этот класс. Мне надо получить

EI>в какую-нибудь переменную вывод этого метода...
можно; в зависимости от того что понимать под 'у меня GUI морда, которая использует этот класс' (це либа или метод в .h или метод в .сpp) и уровня разрешенного воздействия:
0. переписать метод (и весь класс заодно)
1. добавить доп. вывод куда надо прямо в код метода после каждого printf()
2. переопределить printf() (define/undef) на время выполнения метода
3. переопределить stdout на время выполнения метода как дефайн (ой хз что получиццо)
5. переопределить stdout на время выполнения метода как дескриптор и далее читать файлик
6. переопределить printf внешне через LD_PRELOAD если линух, или доступными средствами ОС, если ОС !линух.
7. в конце концов написать свой метод делающий тоже самое, что ли.. =)
8. еще как-нить хакнуть
Re: Переопределение stdout / cout
От: alsemm Россия  
Дата: 14.11.08 16:17
Оценка:
Здравствуйте, e-Inventor, Вы писали:

EI>Здравствуйте


EI>у меня следующая проблема... есть некий класс, у которого есть метод print()

EI>исторически так сложилось, что внутри этого метода используется printf()
EI>который пишет в stdout и менять это нельзя

EI>у меня GUI морда, которая использует этот класс. Мне надо получить

EI>в какую-нибудь переменную вывод этого метода...
Классика жанра, блин

Вас спасет SetStdHandle. В двух словах — делаете pipe через CreateFile, этот пайп привязываете к stdout через SetStdHandle. Заупускаете отдельную нитку, в которой читаете из пайпа (писать в него неявно будут printf-ы). Еще надо не забыть синхронизировать std::cout и компанию — ios::sync_with_stdio().
По теме читать тут:
http://support.microsoft.com/kb/q105305/
http://www.halcyon.com/~ast/dload/guicon.htm
http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx

Алексей
Re[2]: Переопределение stdout / cout
От: e-Inventor Россия  
Дата: 16.11.08 09:16
Оценка:
A>Вас спасет SetStdHandle. В двух словах — делаете pipe через CreateFile, этот пайп привязываете к stdout через SetStdHandle. Заупускаете отдельную нитку, в которой читаете из пайпа (писать в него неявно будут printf-ы). Еще надо не забыть синхронизировать std::cout и компанию — ios::sync_with_stdio().
A>По теме читать тут:
A> — http://support.microsoft.com/kb/q105305/
A> — http://www.halcyon.com/~ast/dload/guicon.htm
A> — http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx

Большое спасибо за дельный совет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.