如何在使用动态库时抑制输出?

时间:2011-01-21 14:54:39

标签: c dynamic-linking

我实际上有 解决这个问题的方法,但我想知道是否有一个更光滑的问题。

我需要使用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));
}

有什么建议吗?

5 个答案:

答案 0 :(得分:2)

您可以尝试使用setvbufstdout设置为具有非常大的缓冲区并进行完全缓冲。然后,在每次调用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;
}

答案 1 :(得分:2)

我有一个建议,它允许你使用预处理器来实现可移植性,或者可能是“可移植性”。

如果您尝试类似

的话
#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"获得预定义的宏。

答案 2 :(得分:0)

在Windows中,您也可以重定向流。 见http://support.microsoft.com/kb/110930/en-us

答案 3 :(得分:0)

不幸的是,freopning到特定于平台的空文件名大约是你在标准C中可以得到的最接近的文件。你也可以考虑修改库本身,以便不在stdout上输出这么多的输出。

也就是说,在实践中,您需要担心的唯一操作系统是基于unix(包括MacOS)或Windows - 在Windows的情况下,stdout默认是隐藏的,因此您可以跳过重定向步骤,而对于* nix,你已经有了代码。

答案 4 :(得分:0)

对于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

为我工作。