我正在使用静态库,它使用printf()生成std输出。我如何拦截它,以便在我的应用程序中显示输出结果并进行突出显示?如何在C++代码中拦截printf()?
我有lib的来源,我可以稍微修改它,如果需要。
我正在使用静态库,它使用printf()生成std输出。我如何拦截它,以便在我的应用程序中显示输出结果并进行突出显示?如何在C++代码中拦截printf()?
我有lib的来源,我可以稍微修改它,如果需要。
我能使用freopen(..);
做到这一点: http://www.cplusplus.com/reference/cstdio/freopen/
是什么?你什至没有说什么重新打开,并为此OS –
我修改了答案和提供的链接 – 4ntoine
我的lib的来源,如果需要,我可以稍微修改它。
好吧,如果你真的相信他们正在使用printf
,你可以建立自己的代码,你可以使用对他们,只要你没有在那里等场所使用printf
。
(我假设一个类Unix平台上,所以有可能需要做一些修改,以得到这个工作在其他地方。)
一两件事你可以做的是重新定义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
功能上面就像replacement_printf
,然后你要说服链接器,而不是链接到您的版本的标准库的。您可能只需将您的printf
粘贴到您的某个编译单元中即可完成;当熟料链接您将重定向到您的源的库时,它会找到您的printf并链接到它;那么稍后当它看到标准库中的一个时,它会放弃它,因为那时没有任何东西叫它。
如果这不起作用,可以尝试使用ar
和ranlib
命令将printf
放入您自己的库中,然后将该库链接到您重定向的库之后。
请注意,如果您尝试重定向的库是共享库(如DLL或.so文件),则可能无法使用;它在制造时与标准printf
相连。
这条路线有更多的警告,取决于你的链接器是如何工作的以及其他一些事情,所以我不推荐它,但为了完整性我将它包括在内。
这里有类似的问题的答案:http://stackoverflow.com/questions/5911147/how-to-redirect-printf-output-back-into-code and here: http://stackoverflow.com/questions/1599109/redirecting -printf 两者都建议使用管道来捕获stdout输出,并设置单独的线程/进程来拦截它。这些答案可能值得一看。 – quercus32