马尔亚之战 西瓜影音:如何用C++写Tck/Tk的DLL模块

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 14:12:17

如何用C++写Tck/Tk的DLL模块

因为实习要做一个工程设计软件,考虑到移植性和编写效率,是用脚本语言Tcl/Tk编写的,里面有一块是列车运行计算仿真的部分,老板觉得用Tcl /Tk这种脚本语言的运行效率太低,于是要求这一块计算用C完成,而这一部分是我干的,于是花了一天,花了吃奶的力气总算搞清楚这个接口部分是怎么弄了。

其实网上有不少的讨论和教程,但并不是每一个都可以用的,原因就是早期Tcl/Tk的内部变量类型都是String,而后期修改成了一个叫做Tcl_obj 的多接口类型,如果能够知道这一点,就可以绕过不少弯路。

此外Tcl/Tk的入口函数名字叫"模块名_Inti",首先这个函数名是要区分大小写的,第二,在所有C++编译器导出的时候,这个函数都要加修饰符extern "c",否则因为编译的过程中函数名会被C++编译器修改为可支持重载的形式,这样的话DLL导出后Tcl/Tk就找不到入口函数了。用C编译器应该没有这个问题。

下面是我做的一个原型的源代码

#include   
int tkse_entry(ClientData cdata, Tcl_Interp*interp, int objc, Tcl_Obj*CONST objv[]){
    Tcl_SetObjResult(interp, Tcl_NewStringObj("Train Kinematics Simulation Engine", -1));
    return TCL_OK;
}
extern "C" {
int Tkse_Init(Tcl_Interp*interp){
    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
        return TCL_ERROR;
    if (Tcl_PkgProvide(interp, "Train_Kinematics_Simulation_Engine", "0.1") == TCL_ERROR)
        return TCL_ERROR;
    Tcl_CreateObjCommand(interp, "tkse", tkse_entry, NULL, NULL);
        return TCL_OK;
}
}

为了少引用一个windows.h库,我把宏EXTERN_C DLLEXPORT直接还原成extern "c" {}了,这样反而看上去比较干净。

编译用的是MinGW的g++,用Cygwin的g++也是可以编译的,出来的是Linux的动态连接库.so,不过还是可以在windows的Tcl/Tk下面用的。至于微软的编译器,还没有试过,因为据说VC7.1之后所有的编译器编译出来的程序,运行的时候需要.net framework的支持,这样就没法做到移植去其它平台了,所以就没有去尝试。

编译命令(直接写成.bat放在源文件同一个目录下运行)

set path=C:\Program Files (x86)\MinGW\bin
g++ -I C:\Progra~2\Tcl\include -s -shared -o tkse.dll tkse.cpp C:\Progra~2\Tcl\bin\tcl85.dll

然后同一个目录下写一个.tcl文件,名字不要和 DLL的入口命令一样,里面写一行

console show

load tkse.dll

保存,双击打开

输入tkse就可以看到cpp里面写好的输出了。