Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Предположим, я использую стороннюю библиотеку, которую линкую в плагин, т.е., ее код исполняется непосредственно в процессе Фара.
И вот эта библиотека где-то там у себя внутри вдруг пишет в stdout (и stderr) всякое, и оно, соответственно, прям поверх красивого синего Фара серым цветом изображается.
Кто-нибудь с такой проблемой сталкивался и решал ли? Какие идеи? Тупейшее лобовое закрытие перед вызовом, а потом переоткрытие stdout'а после -- не срабатывает, то есть надо ковыряться. Понятно, что так или иначе проблему решить можно, но, может, в Фаре есть какая-то готовая функциональность для этого?
И вот эта библиотека где-то там у себя внутри вдруг пишет в stdout (и stderr) всякое, и оно, соответственно, прям поверх красивого синего Фара серым цветом изображается.
Кто-нибудь с такой проблемой сталкивался и решал ли? Какие идеи? Тупейшее лобовое закрытие перед вызовом, а потом переоткрытие stdout'а после -- не срабатывает, то есть надо ковыряться. Понятно, что так или иначе проблему решить можно, но, может, в Фаре есть какая-то готовая функциональность для этого?
- DrKnS
- Posts: 6114
- Joined: Thu 04 Aug, 2005 06:44
- Location: Kyiv
- Has thanked: 12 times
- Been thanked: 426 times
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Если вы будете играться с перенаправлением stdout, то поломаете вывод самого фара.
Кроме того, ничто не мешает библиотеке напрямую открывать CONOUT$.
Поэтому или уносить в отдельный процесс, или просить автора библиотеки так не делать.
Кроме того, ничто не мешает библиотеке напрямую открывать CONOUT$.
Поэтому или уносить в отдельный процесс, или просить автора библиотеки так не делать.
- DrKnS
- Posts: 6114
- Joined: Thu 04 Aug, 2005 06:44
- Location: Kyiv
- Has thanked: 12 times
- Been thanked: 426 times
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Стандартный наверное можно заткнуть каким нибудь freopen("nul","w",stdout).
Только не забудьте потом поставить обратно, т. к. другие могут использовать его для вполне легитимных целей.
Только не забудьте потом поставить обратно, т. к. другие могут использовать его для вполне легитимных целей.
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Вот как раз "поставить назад" не получалось. То есть, и полное закрытие и перенаправление работало, а когда потом "ставил назад", фар затихал секунды на 3 и падал.
Я, в общем, не копал, просто решил сначала спросить, чтоб, в случае чего, не ломиться в открытые ворота. Ну, покопаю тогда.
Я, в общем, не копал, просто решил сначала спросить, чтоб, в случае чего, не ломиться в открытые ворота. Ну, покопаю тогда.
-
- Posts: 6834
- Joined: Thu 23 Mar, 2006 21:36
- Location: Israel
- Has thanked: 41 times
- Been thanked: 530 times
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Как вариант может сгодиться обёртка вызовов функций библиотеки парой FCTL_GETUSERSCREEN/FCTL_SETUSERSCREEN.
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
В общем, проблему нашел, к ФАРу она отношения не имеет. На всякий случай напишу тут, а то вдруг кто напорется.
Проблемой является откровенный маразм в заголовочных файлах M$.
В corecrt_wstdio.h (это Windows 10 SDK -- у них теперь CRT частично в Windows SDK входит) написано такое:
Т.е., любой код, который копирует структуру FILE, копирует только sizeof(void*) байтов. И мой код (это я stdout "на место возвращаю") в том числе.
И если переопределить структуру FILE нормально (как например, в mingw-w64), или скопировать нужное количество байтов руками, то всё начинает работать нормально.
Ну, я, типа, понимаю, что правильные с точки зрения MS разработчики не должны хотеть копировать структуру FILE, а должны воспринимать ее сугубо как opaque и никогда не разыменовывать указатели на нее. Но вообще, это дичь какая-то. Похоже, это у них началось с момента перетряхивания структуры CRT.
Проблемой является откровенный маразм в заголовочных файлах M$.
В corecrt_wstdio.h (это Windows 10 SDK -- у них теперь CRT частично в Windows SDK входит) написано такое:
Code: Select all
typedef struct _iobuf
{
void* _Placeholder;
} FILE;
Code: Select all
*stdout = ...
И если переопределить структуру FILE нормально (как например, в mingw-w64), или скопировать нужное количество байтов руками, то всё начинает работать нормально.
Ну, я, типа, понимаю, что правильные с точки зрения MS разработчики не должны хотеть копировать структуру FILE, а должны воспринимать ее сугубо как opaque и никогда не разыменовывать указатели на нее. Но вообще, это дичь какая-то. Похоже, это у них началось с момента перетряхивания структуры CRT.
- DrKnS
- Posts: 6114
- Joined: Thu 04 Aug, 2005 06:44
- Location: Kyiv
- Has thanked: 12 times
- Been thanked: 426 times
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Почему дичь? Стандарт явно запрещает разыменовывать и копировать FILE*, содержимое и размер структуры нигде не оговорены и ваше ручное копирование байтов вполне может вычурно отвалиться при первом же апдейте CRT.
Лучше использовать что-то типа _fdopen(_dup(_fileno(stdout)), "w").
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
stdout это rvalue, вы не можете ему ничего присвоить.
написать нельзя.
Вы сначала делаетепотом зовете нужную функцию, а потом "возвращаете" stdout с помощью
Но если стандарт запрещает копировать FILE, значит либо подобные вещи в общем случае вообще нельзя делать, либо делать не на уровне CRT.
написать
Code: Select all
stdout = _fdopen(old_stdout, "w")
Вы сначала делаете
Code: Select all
int old_stdout = _dup(1)
Code: Select all
*stdout = * _fdopen(old_stdout, "w")
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Чтобы не работало, нужен *новый* Windows 10 SDK, который ставится, например, с VS 2017RC и, возможно, с VS2015. У меня есть гипотеза, что с более старыми студиями (до перетряски CRT) оно тоже работает, как, например, оно прекрасно работает с mingw-w64 gcc.Shmuel wrote:У меня почему-то работает.
Под новым Windows 10 SDK код уважаемого DrKnS падает, хотя он, судя по всему, корректнее, поскольку не копирует FILE.
- DrKnS
- Posts: 6114
- Joined: Thu 04 Aug, 2005 06:44
- Location: Kyiv
- Has thanked: 12 times
- Been thanked: 426 times
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
У меня на VS2015, SDK v10.0.10240.0 всё работает.
FILE там такой же, как у вас выше.
Если в 2017RC падает - возможно, это баг, есть смысл написать им на https://connect.microsoft.com/VisualStudio
FILE там такой же, как у вас выше.
Если в 2017RC падает - возможно, это баг, есть смысл написать им на https://connect.microsoft.com/VisualStudio
Сторонняя библиотека, *линкуемая* в плагин, пишет в stdout (stderr)
Ха, у меня оказался немного другой код (там был еще fclose(stdout), а потом _fdopen ...), так вот он падал на 2015 и 2017 и работал на 2012 (откопал ее и проверил) и mingw-w64. Я сейчас в точности воспроизвел ваш и он действительно работает на всех версиях.
Вопросы снимаются.
Вопросы снимаются.