11

我在将 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,顺便说一句)并删除 AllocConsole 调用一切正常。有人知道我错过了什么吗?

编辑:只是为了澄清,我正在寻找一种从 C API 中做到这一点的方法。

另一个编辑:Alex 的解决方案是正确的,但是对于使用 Python 3.x 的任何人,您可能会注意到新 API 中缺少 PyFile_FromString 函数。虽然它可能不是最好的选择,但我发现这在 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);
4

2 回答 2

11

在 Python 端设置sys.stdout(大概设置为 an open('CONOUT$', 'wt'))以使 Pythonprint正常工作,对于sys.stderrsys.stdin. (有更快的方法可以从 C 扩展中实现这一点,但最简单的方法是只执行 Python 语句,import sys前面带有 a;-)。

为什么:因为 Python 的运行时,在启动时,发现标准 FD 已关闭,sys.stdout并相应地设置和友元,并且不会再次检查并以不同方式设置它们——所以你只需自己明确地设置它们,就可以了。

如果您热衷于在 C-API 级别完成所有操作,则需要几行代码,但当然可以完成...

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);

这与单个 Python 行完全等效:

sys.stdout = open('CONOUT$', 'wt')
于 2009-11-09T00:42:11.327 回答
1

告诉嵌入式 python 将其输出重定向到文件要容易得多。

试试这个代码:

PyRun_SimpleString("import sys\n");
PyRun_SimpleString( "sys.stdout = sys.stderr = open(\"C:\\embedded_log_file.txt\", \"w\")\n" );
于 2012-06-21T18:00:04.687 回答