【问题标题】:Redirect Embedded Python IO to a console created with AllocConsole将嵌入式 Python IO 重定向到使用 AllocConsole 创建的控制台
【发布时间】:2009-11-09 00:07:44
【问题描述】:

我在将 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);

【问题讨论】:

    标签: python console io-redirection


    【解决方案1】:

    在 Python 端设置 sys.stdout(大概设置为 open('CONOUT$', 'wt'))以使 Python 的 print 工作,sys.stderrsys.stdin 也是如此。 (有更快的方法可以通过 C 扩展实现这一点,但最简单的方法是只执行 Python 语句,前面带有 import sys;-)。

    为什么:因为 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')
    

    【讨论】:

    • 谢谢,我很欣赏这个提示,但我想我应该更明确一点:我正在寻找一种通过 C api 执行此操作的方法。文件/sys API 的文档充其量只是参差不齐。因此,我没有太多运气靠自己解决这个问题。
    • 那里 -- 展示了如何使用 C API 将一行 Python 行转换为 7 行以上(可能更多,取决于错误诊断请求)。 (看看为什么有经验的 Python 和 C-API 编码人员经常建议只从 C 中运行 Python 代码字符串?-)。
    • 我愿意,而且我也喜欢这样。在这种情况下,出于安全考虑,需要在 C API 中执行此操作,因此我无能为力。非常感谢!
    【解决方案2】:

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

    试试这个代码:

    PyRun_SimpleString("import sys\n");
    PyRun_SimpleString( "sys.stdout = sys.stderr = open(\"C:\\embedded_log_file.txt\", \"w\")\n" );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 2016-02-03
      • 2022-01-26
      相关资源
      最近更新 更多