輸出結果的code散佈在很多地方,而且通常是直接出到stdout,想在tcl得到一樣格式
的結果就要慢慢改,有些複雜一點的輸出格式呼叫一堆function,還有static function,
改起來很麻煩。
以下紀錄一下目前用到的幾種導出結果的方法
#include <stdio.h>
#include <stdlib.h>
#include <tcl.h>
int testA();
int testB();
int testC();
static Tcl_Interp *tclInterp;
#ifdef __cplusplus
extern "C"
#endif
int DLLEXPORT
Outputtest_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
return TCL_ERROR;
}
if (Tcl_PkgProvide(interp, "outputtest", "1.0") == TCL_ERROR) {
return TCL_ERROR;
}
tclInterp = interp;
Tcl_CreateCommand(interp, "testA" , testA ,NULL,NULL);
Tcl_CreateCommand(interp, "testB" , testB ,NULL,NULL);
Tcl_CreateCommand(interp, "testC" , testC ,NULL,NULL);
return TCL_OK;
}
//最簡單的一種,如果輸出結果幫你整理好的只要一個 Tcl_SetResult 把結果導出來就好了
int testA()
{
printf("This is TestA stdout\n");
Tcl_SetResult(tclInterp,"This is TestA result",NULL);
return 0;
}
//在包netsnmp時最常遇到這種,一個輸出分成好幾段寫,就只好一行一行看,看到有輸出就補一段 Tcl_AppendResult
int testB()
{
printf("This is TestB stdout\n");
Tcl_AppendResult(tclInterp, "This", NULL);
Tcl_AppendResult(tclInterp, " is", NULL);
Tcl_AppendResult(tclInterp, " TestB", NULL);
Tcl_AppendResult(tclInterp, " result", NULL);
return 0;
}
//在包openssl時,apps太多了,懶的一個一個看,使用取巧的方法
//把stdout導到null (可有可無,沒導的話在cmd下執行這個指令會看到重複的訊息,存到變數一樣只有一個,但是我看不順眼)
//取出值的方法是塞一個buffer去偷資料出來。只要資料不要超過buffer就能一次抓出來,因為我導到NUL,超過buffer資六就會缺
//如果是要跑會出現大量資料的指令可以導到檔案
//(*) close(stdout_save)這句很重要,一開始沒加這行程式跑2000多次就停了,因為OS有開檔案的限制,而 dup 這個 function
// 會開一個新檔
int testC()
{
int stdout_save;
char buffer[10240]={};
fflush(stdout);
stdout_save = _dup(STDOUT_FILENO);
freopen("NUL", "a", stdout);
setvbuf(stdout, buffer, _IOFBF, 10240);
printf("This is TestC");
freopen("NUL", "a", stdout); //redirect stdout to null again
dup2(stdout_save, STDOUT_FILENO); //restore the previous state of stdout
close(stdout_save);
setvbuf(stdout, NULL, _IONBF, 10240); //disable buffer to print to screen instantly
Tcl_AppendResult(tclInterp, buffer, NULL);
return 0;
}
沒有留言:
張貼留言