Почему переменная stdscr не работает в PDCurses?

Моя программа PDCurses завершается, когда я передаю переменную stdscr любой функции, которая получает аргумент WINDOW* (например, keypad и wprintw). Но это работает, когда я перехватываю WINDOW*, возвращенный initscr, и использую его вместо этого.

Я предполагаю, что после вызова initscr возвращаемые им WINDOW* и переменная stdscr должны быть одинаковыми. Но после сравнения их адресов понял, что это не так.

Я мог бы продолжать использовать WINDOW*, возвращаемый initscr, но это не сработает в многотерминальной программе, где нужно использовать newterm, который возвращает SCREEN*, а не WINDOW*. В таком случае мне обязательно нужно было бы использовать переменную stdscr, которая все равно отказывается работать.

Вот пример кода, который работает:

#include <curses.h>

int main()
{
    WINDOW* wnd = initscr();
    wprintw(wnd, "Hello world!");
    refresh();
    endwin();
    return 0;
}

Но это не так:

...
int main()
{
    initscr();
    wprintw(stdscr, "Hello world!"); // the program terminates here
    refresh();
    endwin();
    return 0;
}

Эта потенциально мультитерминальная программа тоже не работает:

...
int main()
{
    SCREEN* term = newterm(NULL, stdout, stdin);
    set_term(term);
    wprintw(stdscr, "Hello world!"); // the program terminates here
    refresh();
    endwin();
    return 0;
}

Поэтому я не знаю, что происходит с переменной stdscr. Я использую Windows 8.1 x64, VC++ x64 Visual Studio 2012 и PDCurses 3.4.0.3 (загружается с помощью диспетчера пакетов Nuget).


person eXe    schedule 03.11.2015    source источник
comment
Поможет короткая примерная программа (PDCurses действительно возвращает stdscr из initscr; возможно, вы объявили конфликтующую переменную).   -  person Thomas Dickey    schedule 04.11.2015
comment
Спасибо. Я добавил пример кода. И да, я упомянул, что могу использовать stdscr, возвращаемый initscr, но мне нужно знать, почему у меня не работает переменная stdscr.   -  person eXe    schedule 04.11.2015


Ответы (2)


Итак, ссылка на Git Issue #31: https://github.com/wmcbrine/PDCurses/issues/ 31

похоже, вы, вероятно, собирали без определения PDC_BUILD_DLL. Как указано в win32/README (позднее win32/README.md, wincon/README.md):

«Когда вы создаете библиотеку как Windows DLL, вы всегда должны определять PDCURSES_DLL_BUILD при компоновке с ней. (Или, если вы хотите использовать только DLL, вы можете добавить это определение в свой curses.h.)»

Описанная модификация была внесена в файлы curses.h, связанные с DLL, которые я распространял на SourceForge, но не в файлы из проекта NuGet, и, по-видимому, соответствующая документация не включена в этот пакет.

person William McBrine    schedule 26.04.2018
comment
Обратите внимание на ошибку здесь в документах 3.4 (исправленную позже) — на самом деле это PDC_DLL_BUILD, а не PDCURSES_DLL_BUILD. Просто чтобы добавить к вашему замешательству. :) (Это правильно, например, в демонстрационных сборках.) - person William McBrine; 27.04.2018

Последняя строка реализации PDCurses initscr() (на самом деле Xinitscr(), которая вызывается initscr(), но тем не менее) просто return stdscr;. Таким образом, нет абсолютно никакой разницы между stdscr и возвращаемым значением initscr().

Я не знаю, что вы делаете неправильно, но я не могу воспроизвести ни одной проблемы с вашей программой-примером. Возможно, вы захотите указать больше о своей среде — ОС, компиляторе, версии PDCurses — и что именно вы интерпретируете как сбой. Кстати, включение stdio.h здесь необязательно (но безвредно).

В любом случае PDCurses не поддерживает несколько одновременных терминалов.

person William McBrine    schedule 04.11.2015
comment
Да, разницы быть не должно, но она не в мою сторону. Я использую Windows 8.1 x64, VC++ v18.00.31101 для x64 (из Visual Studio 2012), PDCurses v3.4.0.3 (загружается с помощью диспетчера пакетов Nuget). Под сбоем я подразумеваю, что программа неожиданно завершается с ошибкой. И да, stdio.h не нужен; Я делал несколько тестов с printf, скомпилированным для C++, и забыл его удалить, извините. Ну а по поводу поддержки нескольких терминалов в PDCurses, то функция newterm на моей стороне работает отлично. - person eXe; 04.11.2015