将SWIG封装的C++类的stdout重定向到非文件的Python对象
我正在尝试把一个用SWIG封装的C模块的输出重定向到一个Python类中。这个SWIG调用者是一个Python类,它已经以以下方式重写了sys.stdout:
with _redirect_streams():
my_C_function(sys.stdout)
try:
out_s = sys.stdout.getvalue()
except AttributeError:
out_s = ""
try:
err_s = sys.stderr.getvalue()
except AttributeError:
err_s = ""
class _redirect_streams(object):
def __enter__(self):
self._orig_stdout = sys.stdout
self._orig_stderr = sys.stderr
sys.stdout = StringIO()
sys.stderr = StringIO()
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stdout = self._orig_stdout
sys.stderr = self._orig_stderr
在SWIG中,我可以把所有的printf输出重定向到一个文件句柄FILE* fh
,这个句柄是我从Python传过去的。
如果我在调用我的C函数时传入sys.__stdout__
(真实的文件对象),那一切都能正常工作。但是如果我传入sys.stdout
,在它被重写之后,它就不再是一个Python文件对象(而是一个StringIO对象),这样C代码就无法输出内容了。
在这种情况下,最好的解决办法是什么呢?
有没有办法在Python中捕获标准输出,同时还能把一个文件类型的句柄传递给C函数呢?
编辑:其实我简化了一点,在我的代码中,my_C_function
仍然是一个Python函数,它在调用SWIG封装的C函数时会在标准输出上打印,而这个C函数则是把内容打印到给定的文件句柄上。
谢谢,
Herve
1 个回答
0
我只能给你提供一种方法。
1. 使用 os.pipe() 来创建一对文件描述符(fd)。
2. 把“写”管道传递给你的 C 代码。
3. 在 C 代码中,用这个管道替换掉“标准输出”(stdout)。
4. 现在,C 代码的标准输出会出现在那个 os.pipe() 的“读”端。
5. 回到 Python 这边,从管道中读取数据,然后写入 Python 的标准输出。
...可能还有更简单的方法...