使用动态库时如何抑制输出?
我实际上对这个问题有一个解决方案,但我想知道是否有更灵活的解决方案。
我需要使用 dlopen 将库加载到我的实用程序中,然后调用其中一个函数。
不幸的是,该函数将一大堆信息喷射到 STDOUT 上,而这是我不想要的。
我有一个不可移植的解决方案,我想知道是否有更好、更通用的解决方案可以使用。
这是我所拥有的(注意:这是C):
/*
* Structure for retaining information about a stream, sufficient to
* recreate that stream later on
*/
struct stream_info {
int fd;
fpos_t pos;
};
#define STDOUT_INFO 0
#define STDERR_INFO 1
struct stream_info s_info[2];
point_stream_to_null(stdout, &s_info[STDOUT_INFO]);
point_stream_to_null(stderr, &s_info[STDERR_INFO]);
void *output = noisy_function();
reset_stream(stderr, &s_info[STDERR_INFO]);
reset_stream(stdout, &s_info[STDOUT_INFO]);
/*
* Redirects a stream to null and retains sufficient information to restore the stream to its original location
*** NB ***
* Not Portable
*/
void point_stream_to_null(FILE *stream, struct stream_info *info) {
fflush(stream);
fgetpos(stream, &(info->pos));
info->fd = dup(fileno(stream));
freopen("/dev/null", "w", stream);
}
/*
* Resets a stream to its original location using the info provided
*/
void reset_stream(FILE *stream, struct stream_info *info) {
fflush(stream);
dup2(info->fd, fileno(stream));
close(info->fd);
clearerr(stream);
fsetpos(stream, &(info->pos));
}
有什么建议吗?
I actually have a solution to this problem, but I'm wondering if there is a slicker one.
I have the need to load in a library to my utility using dlopen
and then call one of the functions.
Unfortunately, the function spews a whole bunch of information out onto STDOUT and this I do not want.
I have a solution that is non-portable and I'm wondering if there's a better, more generic solution that I could use.
Here's what I have (NB: This is C) :
/*
* Structure for retaining information about a stream, sufficient to
* recreate that stream later on
*/
struct stream_info {
int fd;
fpos_t pos;
};
#define STDOUT_INFO 0
#define STDERR_INFO 1
struct stream_info s_info[2];
point_stream_to_null(stdout, &s_info[STDOUT_INFO]);
point_stream_to_null(stderr, &s_info[STDERR_INFO]);
void *output = noisy_function();
reset_stream(stderr, &s_info[STDERR_INFO]);
reset_stream(stdout, &s_info[STDOUT_INFO]);
/*
* Redirects a stream to null and retains sufficient information to restore the stream to its original location
*** NB ***
* Not Portable
*/
void point_stream_to_null(FILE *stream, struct stream_info *info) {
fflush(stream);
fgetpos(stream, &(info->pos));
info->fd = dup(fileno(stream));
freopen("/dev/null", "w", stream);
}
/*
* Resets a stream to its original location using the info provided
*/
void reset_stream(FILE *stream, struct stream_info *info) {
fflush(stream);
dup2(info->fd, fileno(stream));
close(info->fd);
clearerr(stream);
fsetpos(stream, &(info->pos));
}
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我有一个建议,它可以让您使用预处理器来实现可移植性,或者也许是“可移植性”。
如果您尝试类似的操作
(忽略其他操作系统、else case、错误指令等)
然后像以前一样重新打开文件
,这可能会给你你想要的。
不过我还没有在家里尝试过这个。 “nul”文件存在;请参阅Windows 中的/dev/null。您可以在“预定义的C/C++编译器宏”处获取预定义的宏。
I have a suggestion, which lets you use the preprocessor for portability, or perhaps "portability".
If you try something like
(ignoring other OSes, else case, error directive, etc.)
and then reopen the file as before
then that may give you what you want.
I haven't tried this at home, though. The "nul" file exists; see /dev/null in Windows. And you can get predefined macros at "Pre-defined C/C++ Compiler Macros".
您可以尝试使用 setvbuf 设置 stdout 以拥有非常大的缓冲区并进行完全缓冲。然后,在每次调用
noisy_function
后,先清除缓冲区,然后再将其刷新到流中。我认为这会引发未定义的行为。另一种方法是将标准输出重定向到临时文件,就像使用此宏函数一样。
You could try using
setvbuf
to setstdout
to have a very large buffer and be fully buffered. Then, after every call tonoisy_function
, clear out the buffer before flushing it to the stream. I think this invokes undefined behavior though.Another way would be to redirect stdout to a temp file, like with this macro function.
对于 Windows 控制台应用程序:
为我工作。
For Windows console applications:
Worked for me.
在 Windows 中,您也可以重定向流。
请参阅http://support.microsoft.com/kb/110930/en-us
In Windows you can redirect streams too.
See http://support.microsoft.com/kb/110930/en-us
不幸的是,freopening 到特定于平台的空文件名大约是标准 C 中最接近的。您还可以考虑修改库本身,以免在 stdout 上输出太多输出。
也就是说,实际上,您需要担心的唯一操作系统是基于 UNIX(包括 MacOS)或 Windows - 对于 Windows,默认情况下隐藏 stdout,因此您可以跳过重定向步骤,并且对于 * nix 你已经有代码了。
Unfortunately, freopening to a platform-specific null filename is about the closest you can get in standard C. You could also consider modifying the library itself to not spew so much output on stdout.
That said, in practice, the only OSes you need to worry about are either unix-based (including MacOS) or Windows - in the case of Windows, stdout is hidden by default, so you can just skip the redirection step, and for *nix you have the code already.