控制Python脚本的C++输出

lea*_*ner 3 c++ python

我这里有点问题.我有一个Python脚本,它调用从C++编译的二进制文件.Python脚本有自己的一组输出(标准输出和错误),这些输出很容易禁用.C++二进制文件也有自己的输出集(标准输出和错误,以及其他输出); 来源可以改变,但我不是原作者.这是一个问题,因为我不想在我的最终程序中输出C++,我也不希望将来的用户需要编辑C++源代码.

我希望能够做的是有一些Python方法,它将捕获发送到标准输出或错误的C++代码输出.这可能吗?如果是这样,有人会指出我正确的方向吗?

谢谢!!

jco*_*ado 8

一种方法是:

  • 在python中复制文件描述符stdoutstderr使用os.dup.
  • 重定向原件stdoutstderr使用reopen(从C的stdio)写入您选择的文件.

注意:reopen不能直接从python中获得,但您应该能够像下面的示例中那样调用它,或者使用任何其他可用的包装器.

完成后:

  • 每次写入coutcerr使用C++都会写入输出文件.
  • printpython中的每个语句都将写入输出文件.

但是,由于原始描述符是重复的,您仍然可以(参见下面的示例):

  • 打印到原始stdout/ stderr使用sdout.writestdout.err
  • logging正确配置stream参数后使用方法

下面的代码使用即时库来测试使用SWIG包装到python中的真实C++代码,它应该类似于您拥有的库:

import sys, os
import logging
from instant import inline

print 'This is printed from python to stdout'
stdout = os.fdopen(os.dup(sys.stdout.fileno()), 'w')
stderr = os.fdopen(os.dup(sys.stderr.fileno()), 'w')

logging.basicConfig(stream=stderr, level=logging.DEBUG)

redirect = inline("""                                                                                                                    
void redirect(void) {                                                                                                                    
    freopen("my_stdout.txt", "w", stdout);                                                                                               
    freopen("my_stderr.txt", "w", stderr);                                                                                               
}                                                                                                                                        
""")
redirect()

cout = inline("""                                                                                                                        
void cout(void) {                                                                                                                        
    std::cout << "This is written from C++ to my_stdout.txt" << std::endl;                                                               
    std::cerr << "This is written from C++ to my_stderr.txt" << std::endl;                                                               
}                                                                                                                                        
""")
cout()

print 'This is written from python to my_stdout.txt'

stdout.write('This is printed from python to stdout\n')
stderr.write('This is printed from python to stderr\n')
logging.info('This is printed to stderr from python using logging')
Run Code Online (Sandbox Code Playgroud)

此示例的输出是:

$ python test.py
This is printed from python to stdout
This is printed from python to stdout
This is printed from python to stderr
INFO:root:This is printed to stderr from python using logging
$ cat my_stdout.txt 
This is written from C++ to my_stdout.txt
This is written from python to my_stdout.txt
$ cat my_stderr.txt 
This is written from C++ to my_stderr.txt
Run Code Online (Sandbox Code Playgroud)

注意:第一次执行代码时,您可能会收到gcc编译消息(我已删除它们以使示例更清晰).