将嵌入式Python IO重定向到使用AllocConsole创建的控制台 [英] Redirect Embedded Python IO to a console created with AllocConsole
问题描述
我有一些麻烦让Python IO重定向到我为我的Win32应用程序分配的控制台。是否有一个特定于Python的流,我需要重定向?
这里是更多或更少,我现在做的错误检查删除等: / p>
int __stdcall WinMain(/ *这里常用的东西* /){
//创建控制台
AllocConsole ();
SetConsoleTitle(L我的控制台);
//重定向标准IO流到新控制台
freopen(CONOUT $,w,stdout);
freopen(CONOUT $,w,stderr);
freopen(CONIN $,r,stdin);
//测试控制台:
printf(This Works.\r\\\
);
cout<< 所以这个< endl;
// Python Stuff(这是失败的地方)
Py_Initialize();
PyRun_SimpleString(print('I do not work。')\\\
);
Py_Finalize();如果我运行相同的东西,但作为一个控制台应用程序(Visual Studio 05,
}
< BTW)并删除AllocConsole调用一切正常。任何人都知道我错过了什么?
编辑:为了澄清,我正在寻找一种方法来从C API。
YET ANOTHER编辑: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)){
/ *向全世界公布你的错误* /
}
Py_DECREF
Py_DECREF(io);
Py_DECREF(pystdout);
设置 sys.stdout
在Python端(可能是 open('CONOUT $','wt')
/ code>工作,类似 sys.stderr
和 sys.stdin
。 (有更快的方法使这个发生从C扩展,但最简单的方法是只是执行Python语句,一个 import sys
在前面 - )。 / p>
原因:因为Python的运行时,在启动时发现标准FD关闭,因此设置 sys.stdout
并且不会再检查和设置它们不同 - 所以你只是自己设置它们,明确地,它会很好。
如果你渴望做它所有在C-API级别,它将需要几行,但是当然可以做...
PyObject * sys = PyImport_ImportModule(sys);
PyObject * pystdout = PyFile_FromString(CONOUT $,wt);
if(-1 == PyObject_SetAttrString(sys,stdout,pystdout)){
/ *引发错误和非常响亮* /
}
Py_DECREF
Py_DECREF(pystdout);
这完全等同于单个Python行:
sys.stdout = open('CONOUT $','wt')
$ b b
I am having some trouble getting Python IO redirected to a console that I've allocated for my Win32 app. Is there a Python-specific stream that I need to redirect?
Here's more-or-less what I'm doing now (error checking removed, etc.):
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();
}
If I run the same thing but as a console app (Visual Studio 05, BTW) and remove the AllocConsole call everything works. Anyone know what I'm missing?
EDIT: Just for clarification, I am looking for a way to do it from the C API.
YET ANOTHER EDIT: Alex's solution is correct, but for anyone out there using Python 3.x you'll probably notice that the PyFile_FromString function is missing in the new API. While it may not be the best alternative, I found that this works fine in 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);
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')
这篇关于将嵌入式Python IO重定向到使用AllocConsole创建的控制台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!