Python, C: 重定向 stdout 触发 [Errno 9]
我想记录一个用Python和C写的程序的所有输出。但是,从Python打印信息时出现了IOError: [Errno 9] Bad file descriptor
的错误。
请问,有谁知道这是什么问题,怎么解决吗?
附注:我在Windows XP上,使用的是Python 2.6和MinGW GCC。
#include <windows.h>
#include <fcntl.h>
#include "Python.h"
int main()
{
int fds[2];
_pipe(fds, 1024, O_BINARY);
_dup2(fds[1], 1);
setvbuf(stdout, NULL, _IONBF, 0);
/* alternative version: */
// HANDLE hReadPipe, hWritePipe;
// int fd;
// DWORD nr;
// CreatePipe(&hReadPipe, &hWritePipe, NULL, 0);
// fd = _open_osfhandle((intptr_t)hWritePipe, _O_BINARY);
// _dup2(fd, 1);
// setvbuf(stdout, NULL, _IONBF, 0);
write(1, "write\n", 6);
printf("printf\n");
Py_Initialize();
PyRun_SimpleString("print 'print'"); // this breaks
Py_Finalize();
char buffer[1024];
fprintf(stderr, "buffer size: %d\n", read(fds[0], buffer, 1024)); // should always be more than 0
/* alternative version: */
// CloseHandle(hWritePipe);
// char buffer[1024];
// ReadFile(hReadPipe, buffer, 1024, &nr, NULL);
// fprintf(stderr, "buffer size: %d\n", nr); // should always be more than 0
}
1 个回答
2
我觉得这可能跟不同的C运行时有关。你知道的,不同的C运行时之间是不能传递文件描述符的。Python是用MSVC编译的(你需要查一下具体是哪个版本)。所以你可以尝试让MinGW使用相同的C运行时来编译。我记得MinGW里有一些选项可以做到这一点,比如-lmsvcrt80(或者其他合适的版本),但由于许可证的原因,他们不能分发这些库,所以你得在自己的系统上找到它们。抱歉我现在没有更多的细节,但希望这能给你一些搜索的方向。
一个更简单的方法就是全部用Python来做……只需要创建一个类,里面有一个write
方法,可能还需要一个flush
方法,然后把它赋值给sys.stdout。比如说对于一个文件,你可以直接传一个打开的文件对象——对你的管道做类似的事情应该也不难。然后只需导入它和sys,并在PyRun_SimpleString中设置sys.stdout。