python的io重定向,将嵌入式Python IO重定向到使用AllocConsole创建的控制台

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值