gpt4 book ai didi

c - 从自定义命令(Tcl_CmdProc)调用其他Tcl命令

转载 作者:太空宇宙 更新时间:2023-11-04 03:17:42 24 4
gpt4 key购买 nike

乍一看(见下面的证据),似乎当aTcl_CmdProc有控制权时,解释器正在等待它返回,同时不能接受任何其他调用。
那么,在像用户定义函数那样返回之前,我如何调用Tcl呢?我想我可能需要在解释器中设置一个新的调用堆栈框架或其他东西(稍后再释放它)。在这件事上什么也没说。
大局是这样的:
我正在修理AA>。Tcl_CreateCommand man page示例使用Python事件处理程序,这些处理程序在引擎盖下实现为自定义Tcl命令。目前,他们的实现在执行Python代码时释放“Tcl锁”(一个Python特有的锁,它用它包装所有Tcl调用),并在最后将其重新获取到Tcl_SetObjResult,从而允许同时对同一个解释器进行其他调用。
现在,如果在这个时间段内对解释器进行了另一次调用,Tcl很快就会显示一条消息onabortstderr
如果我让自定义命令保留Tcl锁,它稍后将冻结再次获取锁的尝试,因为它本身有时也需要进行Tcl调用。现在,我可以使锁可重入,但是如果不知道如何正确处理解释器,我可能也会破坏它。
为了保持这个问题的主题,我特别询问如何处理解释器,特别是从TclStackFree: incorrect freePtr. Call out of sequence?调用Tcl。具体情况仅供说明,以说明我的需要。如果这真的在一些我找不到的文档中被解释,链接到它并背诵一些要点就足够了。

最佳答案

要从C代码调用Tcl命令,您可以在两个API函数族之间进行选择。一个是Tcl_EvalObjv,另一个是Tcl_Eval。每个都有许多变体,但我要提到的唯一变体是Tcl_EvalObjEx
Tcl_EvalObjv
此函数调用单个Tcl命令,不处理参数中的替换(当然,除非命令本身执行这些操作)。它有这个签名:

int Tcl_EvalObjv(Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[],
int flags);

它以Tcl值引用的C数组的形式(在参数 objv中)描述要调用的命令和传递给它的参数,其中数组的长度为 objc;Tcl保证不会修改数组本身,但如果它进行类型转换,则可以转换值。所有值都必须具有非零引用计数(并且所有值都以其出生 Tcl_NewObj调用的零引用计数开始)。 interp是解释器上下文, flags通常可以为零。
结果是一个Tcl异常代码;如果它是 TCL_OK,则可以使用 Tcl_GetObjResult从解释器检索调用的结果,如果异常代码是 TCL_ERROR,则会出现错误,您通常应该将其传递出去(可能会使用 Tcl_AddErrorInfo添加到堆栈跟踪)。其他异常代码是可能的;通常最好直接传递那些异常代码而不做任何进一步的处理(除非您正在进行类似于循环的操作,这时您应该注意 TCL_BREAKTCL_CONTINUE)。
Tcl_Eval
此函数计算Tcl脚本,而不仅仅是单个命令,它还包括处理参数中的替换。它有这个签名:
int Tcl_Eval(Tcl_Interp *interp,
const char *script);

script是任何旧的C字符串;Tcl不会修改它,但它会解析、字节码编译并执行它。由您来提供脚本的形式,将执行一个单一的命令,没有惊喜。 interp参数和函数调用的结果与 Tcl_EvalObjv相同。
如果您对使用这个命令运行单个命令感兴趣,那么实际上最好使用 Tcl_EvalObjv或…
Tcl_EvalObjEx
这与 Tcl_Eval类似,只是它将脚本作为Tcl值引用(并且也采用 flags)。
int Tcl_EvalObjEx(Tcl_Interp *interp,
Tcl_Obj *objPtr,
int flags);

同样,在将 objPtr传递给此函数之前,请确保它具有非零的引用计数。(它可以在执行过程中调整引用计数。)同样, interp和结果被记录为 Tcl_EvalObjv,并且 flags也是。
调用单个命令的好处是,可以调用 Tcl_NewListObj(或任何其他列表生成函数)来生成脚本值;这样做可以保证不会出现意外的替换。但也可以直接使用 Tcl_EvalObjv调用命令。但是,如果您想处理任何比简单调用一个命令更复杂的事情,那么这是一个很好的起点,因为它有一个普通的 Tcl_Eval没有的关键优势:它可以使通过 objPtr传入的脚本类型成为缓存编译的字节码的脚本类型,在某些情况下允许相当合理的性能提高。
注意 Tcl_EvalObjv实际上是Tcl内部调用以调用所有用户代码并执行所有I/O的API。(“有效”是因为Tcl 8.6中的事情变得更复杂。)
Tcl_CmdProc中,所有这些函数都可以照常调用,不需要特殊处理或“处理解释器”。如果这对您不起作用,导致崩溃或其他什么,解释器没有错,您的代码一定有其他问题。

关于c - 从自定义命令(Tcl_CmdProc)调用其他Tcl命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49842937/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com