Toj*_*oji 10 python console io-redirection
我在将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();
}
Run Code Online (Sandbox Code Playgroud)
如果我运行相同的东西,但作为控制台应用程序(Visual Studio 05,BTW)并删除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);
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 10
设置sys.stdout在Python端(可能是一个open('CONOUT$', 'wt'))以使Python print工作,并且类似于sys.stderr和sys.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);
Run Code Online (Sandbox Code Playgroud)
这与单个Python行完全等效:
sys.stdout = open('CONOUT$', 'wt')
Run Code Online (Sandbox Code Playgroud)