控制 C++ Python 脚本的输出

发布于 2024-12-21 04:55:34 字数 275 浏览 0 评论 0 原文

我这里有一点问题。我有一个 Python 脚本,它调用从 C++ 编译的二进制文件。 Python 脚本有自己的一组输出(标准输出和错误),可以轻松禁用。 C++ 二进制文件也有自己的一组输出(标准输出和错误等);来源可以更改,但我不是原作者。这是一个问题,因为我不希望最终程序中出现 C++ 输出,而且我也不希望未来的用户需要编辑 C++ 源代码。

我想要做的是有一些 Python 方法可以捕获发送到标准输出或错误的 C++ 代码的输出。这可能吗?如果是这样,有人可以指出我正确的方向吗?

谢谢你!!

I have a bit of an issue here. I have a Python script which calls binaries compiled from C++. The Python script has its own set of outputs (to standard out and error), which are easily disable-able. The C++ binaries have their own set of outputs (to standard out and error, among others) as well; the source can be altered, but I am not the original author. This is an issue because I do not want the C++ output in my final program, and I also don't want future users to need to edit the C++ source.

What I'd like to be able to do is have some Python method which will catch the C++ code's output that is sent to standard out or error. Is this possible? If so, could someone point me in the right direction?

Thank you!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜嗑 2024-12-28 04:55:34

一种方法是:

  • 在 python 中使用 os.dup 复制 stdout 和 stderr 的文件描述符。
  • 使用 reopen(来自 C 的 stdio)重定向原始 stdoutstderr 以写入您选择的文件。

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

完成此操作后:

  • C++ 中对 coutcerr 的每次写入都会写入输出文件。
  • python 中的每个 print 语句都会写入输出文件。

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

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

以下代码使用 instant 库,用于测试使用 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')

此示例的输出为:

$ 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

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

One way to do this is:

  • Duplicate in python the file descriptors for stdout and stderr using os.dup.
  • Redirect the original stdout and stderr using reopen (from C's stdio) to write to a file of your choice.

Note: reopen isn't available directly from python, but you should be able to call it as in the example below or using any other wrapper available.

After this is done:

  • Every write to cout and cerr in C++ will write to the output files.
  • Every print statement in python will write to the output files.

However, since the original descriptors are duplicated, you can still (see example below):

  • Print to the original stdout/stderr using sdout.write and stdout.err
  • Use logging methods after configuring properly the stream parameter

The following code uses instant library to test real C++ code that is wrapped into python using SWIG and that should be similar to the library that you have:

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

The output for this example is:

$ 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

Note: First time the code is executed, you might get gcc compilation messages (I've removed them to make the example clearer).

还给你自由 2024-12-28 04:55:34

您是否使用subprocess来编译C++?如果是这样,您可以设置 stderr 和 stdout 的位置:

nowhere = StringIO()
subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)

Are you using subprocess to compile the C++? If so, you can set where stderr and stdout go:

nowhere = StringIO()
subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文