如何从c调用回调tcl过程

时间:2014-02-25 08:51:54

标签: c callback tcl swig

我正在研究Tcl。并使用swig用C扩展TCL命令 现在,我希望C中的扩展命令回调tcl过程。 但我不知道。

请帮帮我。

首先,我在swig中实现一个调度函数,调用mrecv。 在我的tcl脚本中。我打电话给mrecv接收消息。所以,当消息到达时,我希望mclv可以通知tcl。这就是为什么我需要找到一种从c。

调用回调tcl过程的方法

我的代码很简单

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中的过程名称。

1 个答案:

答案 0 :(得分:2)

您需要查看执行Tcl脚本的Tcl_Eval函数系列。这些第一个参数是一个指向脚本运行的Tcl解释器的指针;并且指针是当前的interpeter是传递给SWIG将生成的C函数的参数之一。

目前,您的testCallback()函数会创建一个新的Tcl_Interp,并在该新的interp中评估该命令。你想要做的是在你运行mrecv 3000的同一个Tcl_Interp中评估命令。

为了做到这一点,你必须说服SWIG将Tcl_Interp传递给你的mrecv函数,我认为你可以使用SWIG typemap功能来实现这一点。

如果您创建新的typemap:

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

并将您的函数签名更改为:

W16 mrecv(int timeout, Tcl_Interp *interp)

然后SWIG 自动将Tcl_Interp传递到mrecv函数,而无需更改Tcl代码。

有关typemap源代码的信息,请参见here,有关in type的更多信息,请参阅here