2014-06-24 29 views
1

我正在使用静态库,它使用printf()生成std输出。我如何拦截它,以便在我的应用程序中显示输出结果并进行突出显示?如何在C++代码中拦截printf()?

我有lib的来源,我可以稍微修改它,如果需要。

+0

这里有类似的问题的答案:http://stackoverflow.com/questions/5911147/how-to-redirect-printf-output-back-into-code and here: http://stackoverflow.com/questions/1599109/redirecting -printf 两者都建议使用管道来捕获stdout输出,并设置单独的线程/进程来拦截它。这些答案可能值得一看。 – quercus32

回答

2

我的lib的来源,如果需要,我可以稍微修改它。

好吧,如果你真的相信他们正在使用printf,你可以建立自己的代码,你可以使用对他们,只要你没有在那里等场所使用printf

(我假设一个类Unix平台上,所以有可能需要做一些修改,以得到这个工作在其他地方。)

一两件事你可以做的是重新定义printf指向你自己的版本。另一种方法是编写自己的printf并将其链接到标准库之前。这两条路线都不是你认为推荐的做法,尽管它们应该可行。这两条路线都不需要修改图书馆的来源。

重新定义的printf

在这里,我们只是告诉它,它真是一个不同功能的printf编译器的概念混乱。加入这样的事情你的Makefile:

CFLAGS += -Dprintf=redirected_printf 
CXXFLAGS += -Dprintf=redirected_printf 

(有些编译系统使用变量DEFINES为了这个目的,因人而异。)

这告诉编译器与redirected_printf更换标识printf的每个实例。这与您将#define printf redirected_printf置于每个源文件的顶部相同。

现在你只需要编写redirected_printf函数。我倾向于将格式化传递给stdio中的另一个函数vasprintf,它与printf执行相同的操作,但它需要va_list而不是...,并返回一个指向具有输出的堆分配字符串的指针。

#include <stdarg.h> 
#include <stdio.h> 
extern "C" int redirected_printf(const char * format, ...) { 
    // Make formatted string. 
    char* outstr = 0; 
    va_list ap; 
    va_start(ap, format); 
    int result = vasprintf(&outstr, format, ap); 
    va_end(ap); 
    if(result < 0) // Error occurred and `outstr` undefined if result < 0. 
     return result; 

    // Do something with the string in `outstr` here, like display it in a dialog. 

    // Clean up and return. 
    free(outstr); 
    return result; 
} 

更换的printf

这是有点麻烦,因为你必须写一个名为printf功能上面就像replacement_printf,然后你要说服链接器,而不是链接到您的版本的标准库的。您可能只需将您的printf粘贴到您的某个编译单元中即可完成;当熟料链接您将重定向到您的源的库时,它会找到您的printf并链接到它;那么稍后当它看到标准库中的一个时,它会放弃它,因为那时没有任何东西叫它。

如果这不起作用,可以尝试使用arranlib命令将printf放入您自己的库中,然后将该库链接到您重定向的库之后。

请注意,如果您尝试重定向的库是共享库(如DLL或.so文件),则可能无法使用;它在制造时与标准printf相连。

这条路线有更多的警告,取决于你的链接器是如何工作的以及其他一些事情,所以我不推荐它,但为了完整性我将它包括在内。