TCL作为一种工具语言已经在很多地方得到广泛的应用,在土木方面著名的例子就是ANSYS了。当然作为UCB开发的OpenSees自然也是要用自家的TCL语言了,不过最新的OpenSees源代码中已经增加了对于Python语言的支持。虽然官方尚没有公开Python的使用方式,但是相信应该很快就可以看到使用Python语言建立OpenSees模型了。OpenSees作为一个C++编写的软件,如果用C++实现一个类似于ANSYS中的APDL语言,会大大增加工作量,因此在使用TCL语言建模时需要调用TCL解释器对tcl脚本进行解析,这也是在安装OpenSees的时候需要先安装tcl/tk的原因。
如果有同学安装了Python的集成包,比如Anaconda或者Winpython之类,就会发现不需要安装tcl/tk就可以运行OpenSees了,我自己的电脑就没有安装OpenSees官网提供的tcl/tk安装程序而能够直接运行64位的OpenSees。为了能够自己实现C++中调用TCL解释器,首先还是要安装一下ActiveTcl的,我自己安装的是32位ActiveTcl,这并不影响我电脑运行64位的OpenSees,因为OpenSees调用的是Anaconda中64为的tcl86.dll。
回归主题,因为我自己使用的是32为gcc编译器,因此为了比较好的继承性,我直接下载了32位的ActiveTcl,下载地址可以从ActiveTcl官网找到,这里给一个ActiveTcl 8.5的下载链接:点击下载
PS:目前最新的ActoveTcl是8.6,64位(20230719)
下载之后直接安装到C:\Program Files\Tcl目录下即可,打开Qt Creator新建一个Project:
选择Qt Console Application,因为我只是建立一个测试程,选择Choose…后设置项目的名称和路径:
完成之后需要做一件重要的事情就是将Tcl目录下的include和lib复制到工程文件夹E:\QT\tcltest\tcltest下并从新命名为tcltkinclude和tcltklib:
C++(QT)调用TCL解释器
C++(QT)调用TCL解释器
然后回到Qt Creator中右键工程文件夹,选择添加库…:
C++(QT)调用TCL解释器
选择外部库:
C++(QT)调用TCL解释器
在外部库的设置页面,选择tcktklib中的tcl85.lib,链接选择动态,将“为debug版本添加‘d’作为后缀”选项去掉,点击下一步完成添加:
C++(QT)调用TCL解释器
这时候pro文件中自动增加了tcl85的库文件,但是还缺少头文件的位置,因此增加INCLUDEPATH += $$PWD/tcltkinclude到pro文件中去,这样pro文件应该与下面一致:
QT += coreQT -= gui CONFIG += c++11TARGET = tcltestCONFIG += consoleCONFIG -= app_bundleTEMPLATE = appSOURCES += main.cpp INCLUDEPATH += $$PWD/tcltkinclude unix|win32: LIBS += -L$$PWD/tcltklib/ -ltcl85 INCLUDEPATH += $$PWD/tcltklib DEPENDPATH += $$PWD/tcltklib
然后回到main.cpp直接Ctrl+R运行一下,如果没有出错会出现一个黑框框。然后在main.cpp中增加include “tcl.h”,这样在主文件中输入Tcl_就可以看到Qt Creator的智能提示了:
C++(QT)调用TCL解释器
这样环境就部署好了,下面先创建一个test.tcl文件,文件的路径为E:\QT\tcltest\tcltest\test.tcl:
C++(QT)调用TCL解释器
在main.cpp中写入下面的语句:
#include <QCoreApplication>#include <iostream>#include "tcl.h"using namespace std; int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); Tcl_Interp *interp = Tcl_CreateInterp(); int Res; const char *detail; Res = Tcl_EvalFile(interp, "E:/QT/tcltest/tcltest/test.tcl"); detail = Tcl_GetStringResult(interp); if (Res != TCL_OK) { cout<<"Failed!"<<endl; cout<<detail<<endl; } else { cout<<"Success!"<<endl; } Tcl_DeleteInterp(interp); return a.exec(); }
稍微解释一下,需要先生成一个解释器实例,Tcl_CreateInterp()用于创建这个实例并返回Tcl_Interp *的指针。具体可以参看Tcl的C接口帮助文档,然后使用了两个函数Tcl_EvalFile()和Tcl_GetStringResult()。
Tcl_EvalFile()需要两个参数,第一个是解释器的指针,即刚才创建的interp这个指针, 第二个为文件路径,注意在Qt中需要使用正斜杠/代替Windows的反斜杠\,否则会出错。Tcl_EvalFile()会返回一个下面之一的整数表示执行结果:
- 0 (TCL_OK)
- 1 (TCL_ERROR)
- 2 (TCL_RETURN)
- 3 (TCL_BREAK)
- 4 (TCL_CONTINUE)
Tcl_GetStringResult()可以从解释器接受解释器的信息,这个信息不是程序中的输出信息,是解释器解释tcl失败的原因,可以用来辅助调试。
这里我用没有用qDebug()而是直接用了cout输出到控制台,直接使用Ctrl+R执行之后就可以看到黑框框里面直接输出“orycho”和“Success!”表明调用tcl解释器成功:
C++(QT)调用TCL解释器
至此,成功在C++中调用TCL解释器对tcl文本文件进行解释。
标签:解释器,QT,TCL1,TCL,C++,Tcl,tcl From: https://blog.51cto.com/u_12597366/7977261