我正在使用靜態庫,它使用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