#c #qt
#c #qt
Вопрос:
Я создаю класс, который улавливает все выходные данные консоли и сбрасывает их в один журнал. Мне это нужно, потому что моя программа использует много сторонних библиотек, которые я не могу изменить. Полезная информация из этих библиотек выводится на консоль несколькими способами. Я знаю о замене cout
/ cerr
с помощью пользовательского буфера потока rdbuf
. Мне не нужна помощь в этом. Я также знаю о создании канала для захвата вывода в стиле c, например fprintf( stdout, "Hello, world!" )
. Однако, в отличие от пользовательского буфера потока, где я могу обрабатывать вывод по мере его поступления, вывод в стиле c теперь застрял в этом канале, и мне приходится периодически очищать все и читать из него. Я бы предпочел получить уведомление или установить обратный вызов для обработки ввода по каналу, как это происходит.
Qt здесь тоже присутствует. Я играл с QSocketNotifier
классом, но, похоже, он не работает с файловыми дескрипторами чтения или записи канала.
Предложения?
Комментарии:
1. C и C — это не одно и то же
2. Боюсь, нет способа сделать то, что вы хотите.
3. Это кричит о проблеме X-Y.
4. Просто заблокируйте поток на канале.
5. В каких операционных системах вам это нужно для работы?
Ответ №1:
вывод теперь застрял в этом канале, и мне приходится периодически очищать все и читать из него. Я бы предпочел получить уведомление или установить обратный вызов для обработки ввода по каналу, как это происходит.
Неясно, что такое «все» или почему вам нужно делать больше, чем просто сбрасывать определенные файловые потоки, но это звучит так, как будто вы имеете в виду тот факт, что эти потоки буферизуются, поэтому каналы, к которым вы их подключили, не записываются до тех пор, пока не будут выполнены условия сброса или flush()
не будут выполнены.
Кроме того, мы не знаем, манипулируете ли вы файловыми потоками уровня 3 или файловыми дескрипторами уровня 2. Мы не знаем, отключили ли вы синхронизацию между потоками C и потоками уровня 3.
Все, что сказано, можно отключить буферизацию уровня C 3 с помощью
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
Это означает, что вам больше не нужно flush()
будет, скажем, fprintf()
записывать вызовы в каналы.
Для этого вы можете настроить вызов опроса / выбора для проверки наличия данных в каналах, или вы можете просто заставить потоки выполнять блокирующие чтения из них и передавать данные куда-нибудь еще.
Комментарии:
1. Отключение буферизации уровня C 3 с помощью setvbuf в стандартном выводе / stderr и перенаправление на конец записи канала с использованием dup и dup2 с блокировкой чтения на конце чтения канала в отдельном потоке сработало прекрасно. Спасибо за помощь!
Ответ №2:
В Linux мы используем для перенаправления стандартных потоков:
freopen (outfile, "a", stdout);
freopen (outfile, "a", stderr);
Я не верю, что есть какой-либо способ получить уведомление.
Комментарии:
1. Спасибо за ответ. Я ранее нашел это решение, но оно не выполняет то, что мне нужно. Возможно, мне следовало быть более конкретным в моем вопросе: я искал способ объединить все сообщения консоли в один файл журнала. Захват стандартного вывода / stderr был последним кусочком этой головоломки.