C++(QT)创建自定义TCL命令

cppvtcl

上次完成了在QT中使用C++调用Tcl解释器的任务,这次将会为Tcl解释器增加一些自定义的命令,用来提高用户的操控性。这次的目标是自定义一个length的命令,用来计算平面点之间的坐标,输入形式按照: length x1 y1 x2 y2的形式输入。Tcl解释器截取length命令后调用C++程序完成点(x1, y1)和(x2, y2)距离的计算。因此我们先写一个简单的Tcl测试程序:

这样计算的是一系列点与点(3, 4)之间的距离。上面的代码直接使用Tcl解释器是不能运行的,因为解释器会提示length为未知关键字,因此需要我们为Tcl解释器加一个“壳子”,包装的代码如下所示:

关于Tcl解释器的配置,可以看我之前写的C++(QT)调用TCL解释器。这里主要说几个命令:

Tcl_CreateObjCommand命令用于向Tcl解释器增加一个自定义命令,在这个命令里面,需要指定一个增加命令的解释器,命令的名称,以及处理这个命令调用的函数的这里定义的是length命令,当Tcl解释器遇到length命令的时候,会在C++中调用相应的length函数执行命令,这样我们就可以“截取”我们自定义的命令。

下面根据官方API介绍一下Tcl_CreateObjCommand命令的参数:

  • Tcl_Interp *interp (in): 解释器指针;
  • char *cmdName (in): 命令名称;
  • Tcl_ObjCmdProc *proc (in): 执行cmdName的时候会调用proc函数;
  • ClientData clientData (in): 传递给proc或者deleteProc的参数;
  • Tcl_CmdDeleteProc *deleteProc (in): 在cmdName删除之前解释器会调用deleteProc函数执行一些用户自定义的操作;

创建的length函数格式如下:

clientData与interp由Tcl_CreateObjCommand命令传递过来,argc表示命令的数量,argv则是一个Tcl_Obj的指针数组,这两个东西看上去复杂用起来比较简单。结合我们的length命令:

argc为5表示总共五个参数,包括length本身,而argv[0]~argv[4]指代这四个参数的Tcl_Obj,使用Tcl_GetString()函数可以转换Tcl_Obj为char类型指针,具体可以看上面完整的程序代码。

因此我们运行上面的命令,可以得到下图所示的结果:

C++(QT)创建自定义TCL命令

C++(QT)创建自定义TCL命令

这样就成功的将自定义length命令中的两个点的坐标和长度计算出来了。这也是OpenSees内部处理OpenSees自定义命令的方法。像node, element, EqualDof等等的命令都是OpenSees通过这种方式创建的。当用户加载OpenSees的Tcl脚本时,OpenSees内部通过上述方式获取node的坐标,element的单元类型,然后将这些信息存放在内存中,组成矩阵计算结构响应。

PS: 这篇文章很早就写了一半,无奈教研室网络虽然速度飞快,但是和我服务器的连接很不稳定,50%+的掉包使得网站一直难以更新。。。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Are you human? Click the Apple...