我实际上有a解决此问题的方法,但是我想知道是否有一个光亮的解决方案。
我需要使用dlopen
将库加载到实用程序中,然后调用其中一个函数。
不幸的是,该函数将大量信息喷出到STDOUT上,而我不希望这样做。
我有一个不可移植的解决方案,我想知道是否可以使用更好,更通用的解决方案。
这是我所拥有的(NB:这是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));
}
有什么建议吗?
我有一个建议,可以让您使用预处理器来实现可移植性,或者也许是“可移植性”。
如果您尝试类似的东西
#if defined __unix__
#define DEVNULL "/dev/null"
#elif defined _WIN32
#define DEVNULL "nul"
#endif
((忽略其他操作系统,否则使用大小写,错误指令等)然后像以前一样重新打开文件
FILE *myfile = freopen(DEVNULL, "w", stream);
然后可能会给您您想要的东西。
不过,我还没有在家中尝试过。 “ nul”文件存在;参见/dev/null in Windows。您可以在"Pre-defined C/C++ Compiler Macros"中获得预定义的宏。
您可以尝试使用setvbuf
将stdout
设置为具有很大的缓冲区并被完全缓冲。然后,在每次调用noisy_function
之后,请先清除缓冲区,然后再将其刷新到流中。我认为这会引起未定义的行为。
另一种方法是将stdout重定向到临时文件,例如使用此宏功能。
#include <stdio.h>
#define QUIET_CALL(noisy) { \
FILE* tmp = stdout;\
stdout = tmpfile();\
(noisy);\
fclose(stdout);\
stdout = tmp;\
}
int main(){
QUIET_CALL(printf("blah blah"));
printf("bloo bloo\n");
return 0;
}
在Windows中,您也可以重定向流。参见http://support.microsoft.com/kb/110930/en-us
不幸的是,重新打开特定于平台的空文件名是在标准C语言中可以找到的最接近的文件名。您也可以考虑修改库本身,以免在stdout上产生太多输出。
也就是说,实际上,您唯一需要担心的操作系统要么是基于unix的操作系统(包括MacOS),要么是Windows;对于Windows,默认情况下stdout是隐藏的,因此您可以跳过重定向步骤,然后对于* nix,您已经有了代码。
对于Windows控制台应用程序:
freopen("NUL", "w", stdout); // redirect stdout to the windows version of /dev/null
NoisyDllFunction();
freopen("CON", "w", stdout); // redirect stdout back to the console
为我工作。