2014-02-25 47 views
0

我正在使用Tcl。並使用swig擴展TCL命令。現在,我想讓C中的擴展命令回調tcl過程。 但我不知道。如何從c調用回調tcl程序

請幫幫我。

首先,我在swig中實現了一個調用mrecv的調度器函數。 並在我的tcl腳本。我打電話給mrecv接收消息。所以,當一條消息到達時,我希望tcl可以通過mrecv來通知。那爲什麼我需要找到一種方法來調用c中的回調tcl過程。

我的代碼是breifly是

W16 mrecv(int timeout) { 
    W16 res; 
    Msg_t *msg = NULL; 
    APP_EVENT_T eventList[255]; 
    int listLength = 255; 

    while (1) { 
     readAgain = 0; 
     msg = malloc(sizeof(Msg_t)); 
     if (!msg) { 
      return RETURN_ERR; 
     } 
     memset(msg, 0, sizeof(Msg_t)); 
     res = MsgRecvEvent(msg, eventList, &listLength, timeout); 
     if (res == RETURN_OK) { 
      msgDispatcher(msg); 
     } 
     free(msg); 

    }        
    return res; 
} 
void msgDispather(void *msg) { 
    /*notify tcl*/ 
} 

,在我的TCL腳本。我打電話給mrecv命令。 TCL腳本:

res [ mrecv 3000 ] 

我需要知道如何通知TCL。

以下是我的測試演示。

int testCallback (char * str) { 
    Tcl_Interp *interp; 
    interp=Tcl_CreateInterp(); 
    Tcl_Eval(interp,str); 
    return 0; 
} 

testCallback()是將由tcl調用的擴展cmd。 str是tcl中的過程名稱。

+0

你能讓你的問題更具體嗎?這對於目前的StackOverflow來說有點過於寬泛。到目前爲止你嘗試了什麼,你卡在哪裏? – starsplusplus

+0

你真的不想經常創建口譯員(他們是重量級的),他們不是垃圾收集。您也可能想要使用現有的,以便用戶可以在實際處理回調之前進行設置... –

回答

2

您需要查看執行Tcl腳本的Tcl_Eval系列函數。這些函數將第一個參數作爲腳本運行的Tcl解釋器的指針;並且一個指針指向的是當前的交互參數,它是傳遞給SWIG將生成的C函數的參數之一。

目前您的testCallback()函數會創建一個新的Tcl_Interp並評估該新interp中的命令。你想要做的就是在你運行mrecv 3000的同一個Tcl_Interp中評估命令。

爲了做到這一點,您必須說服SWIG將Tcl_Interp傳遞到您的mrecv函數中,並且我認爲您可以使用SWIG類型映射功能來執行此操作。

如果您創建一個新的類型映射:

%typemap(in,numinputs=0) Tcl_Interp *interp { 
    $1 = interp; 
} 

和你的函數的簽名改爲:

W16 mrecv(int timeout, Tcl_Interp *interp) 

然後痛飲應該自動傳遞Tcl_Interp到您的MRECV功能,無需您需要改變Tcl代碼。

請參閱here以獲取有關typemap的源代碼和here的更多信息,以獲取有關typemap中的更多信息,使其成爲可能。

+0

非常感謝。我詳細說明了我的問題。 – user3350310

+0

@ user3350310我認爲上述現在回答你的問題。 – Jackson

+0

特別是,'Tcl_Eval'用於運行腳本,'Tcl_EvalObjv'用於用文字參數調用單個命令。 –