Перенаправьте Встроенный Python IO к консоли, созданной с AllocConsole

Я испытываю некоторые затруднения при получении Python IO, перенаправленный к консоли, которую я выделил для своего приложения Win32. Существует ли определенный для Python поток, который я должен перенаправить?

Вот более или менее, что я делаю теперь (удаленная проверка ошибок, и т.д.):

int __stdcall WinMain(/*Usual stuff here*/) {
    // Create the console
    AllocConsole();
    SetConsoleTitle(L"My Console");

    // Redirect Standard IO Streams to the new console
    freopen("CONOUT$","w",stdout);
    freopen("CONOUT$","w",stderr);
    freopen("CONIN$","r",stdin);

    // Test the console:
    printf("This Works.\r\n");
    cout << "So Does this" << endl;

    // Python Stuff (This is where it fails)
    Py_Initialize();
    PyRun_SimpleString("print('I don't work.')\n");
    Py_Finalize();
}

Если я выполняю то же самое, но как консольное приложение (Visual Studio 05, BTW) и удаляют вызов AllocConsole, все работает. Кто-либо знает то, что я пропускаю?

Править: Только для разъяснения, я ищу способ сделать это от API C.

ЕЩЕ ОДНО РЕДАКТИРОВАНИЕ: решение Alex правильно, но для любого туда использование Python 3.x Вы, вероятно, заметите, что функция PyFile_FromString отсутствует в новом API. В то время как это не может быть лучшая альтернатива, я нашел, что это хорошо работает в Python 3.x:

PyObject* sys = PyImport_ImportModule("sys");
PyObject* io = PyImport_ImportModule("io");
PyObject* pystdout = PyObject_CallMethod(io, "open", "ss", "CONOUT$", "wt");
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) {
    /* Announce your error to the world */
}
Py_DECREF(sys);
Py_DECREF(io);
Py_DECREF(pystdout);
10
задан Toji 10 February 2010 в 14:46
поделиться

1 ответ

Set sys.stdout on the Python side (presumably to an open('CONOUT$', 'wt')) to make Python's print work, and similarly for sys.stderr and sys.stdin. (There are faster ways to make this happen from a C extension, but the simplest way is to just execute the Python statements, with a import sys in front;-).

Why: because Python's runtime, on startup, found the standard FDs closed, set sys.stdout and friends accordingly, and is not going to check again and set them differently -- so you just set them yourself, explicitly, and it will be fine.

If you're keen to do it all at C-API level, it will take a few lines, but of course it can be done...

PyObject* sys = PyImport_ImportModule("sys");
PyObject* pystdout = PyFile_FromString("CONOUT$", "wt");
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) {
  /* raise errors and wail very loud */
}
Py_DECREF(sys);
Py_DECREF(pystdout);

this is the exact equivalent of the single Python line:

sys.stdout = open('CONOUT$', 'wt')
10
ответ дан 4 December 2019 в 01:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: