Tcl可以轻松地通过用C语言编写命令来进行扩展。一个用C编写的命令比具有同样功能的Tcl程序更有效。用C语言编写程序的另一个原因是,在Tcl中可能没有与C功能完全相同的函数。例如,购置了一台新的彩色扫描仪或者独立的输入设备,而这台设备是通过C程序接口来进行初始化和操作的,那么,如果在用户的终端中没有与之相匹配的程序借口,这台设备就不能在Tcl脚本中访问。

/* main.c */
#include

int AppInit(Tcl_Interp * interp)
{
if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}

return TCL_OK;
}

int main(int argc, char *argv[])
{
Tcl_Main(argc, argv, AppInit);

return 0;
}


main.c 源程序

使用 “gcc -o main main.c -ltcl” 编译即可运行。
注意:编译时可能出现 “Cannot find -ltcl” 错误提示,这是表示libtcl.so库没找到,可能的原因之一是libtcl.so没有正确地链接到libtcl8.5.so(其中的8.5与具体安装的tcl版本有关),可以进入 “/usr/lib” 目录,执行 “ln -s libtcl8.5.so libtcl.so” 修复。
相关链接

上面的例子只是简单地调用tclsh解释器,并没有编写自己的命令,下面这个是编写一个能生成随机数的random命令的例子。

/* mytclsh.c */
#include
#include

/*
* Declarations for application-specific command procedures
*/
Tcl_CmdProc *
RandomCmd(ClientData clientData, Tcl_Interp * interp,
int argc, char *argv[]);
int Tcl_AppInit(Tcl_Interp * interp);

int main(int argc, char *argv[])
{
Tcl_Main(argc, argv, Tcl_AppInit);

return 0;
}

/*
* Tcl_AppInit is called from Tcl_Main
* after the Tcl interpreter has been created,
* and before the script file
* or interactive command loop is entered.
*/

int Tcl_AppInit(Tcl_Interp * interp)
{
/*
* Initialize packages
* Tcl_Init sets up the Tcl library facility.
*/
if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
/*
* Register application-specific commands.
*/
Tcl_CreateCommand(interp, “random”, (Tcl_CmdProc *) RandomCmd,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

return TCL_OK;
}

/*
* RandomCmd –
* This implements the random Tcl command. With no arguments
* the command returns a random integer.
* With an integer valued argument “range”,
* it returns a random integer between 0 and range.
*/
Tcl_CmdProc *
RandomCmd(ClientData clientData, Tcl_Interp * interp,
int argc, char *argv[])
{
int rand, error;
int limit = 0;

if (argc > 2) {
interp->result = “Usage: random ?range?”;
return TCL_ERROR;
}
if (argc == 2) {
error = Tcl_GetInt(interp, argv[1], &limit);
if (error != TCL_OK) {
return error;
}
}
rand = random();
if (limit != 0) {
rand = rand % limit;
}
sprintf(interp->result, “%d”, rand);
return TCL_OK;
}

mytclsh.c 源程序

参考链接:1、Writing Extensions;2、Building a custom tclsh