如何在TCL中运行预编译的C代码?

时间:2018-03-06 08:56:09

标签: c tcl

我想在C中重写一些关键函数以提高速度,我正在处理大量输入数据,因此效益可能很大。

在我的环境中,我没有C编译器,所以我无法在运行期间进行编译"做法。应编译C文件,并从编译文件中调用和执行函数。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

您应该编写一些桥接函数并将其打包到可加载的扩展DLL中(或者适用于您的平台的任何正确的文件扩展名)。

合理的起点是sample extension。它的主要代码是generic/sample.c(它只是一个SHA-1实现,普通的C代码是用旧式编写的)。将其桥接到Tcl的代码在generic/tclsample.c中,由两个函数组成。

  • Sha1_Cmd是在C中实现Tcl命令的代码。该名称是正式任意的,但类型签名不是。其中有趣的Tcl API函数是Tcl_GetIndexFromObjTcl_GetString(也有Tcl_GetStringFromObj,参数略有不同),Tcl_GetIntFromObjTcl_AppendResult,{{1} }和Tcl_SetObjResult。不同寻常的是,函数不会调用Tcl_NewIntObj来处理用户传入错误数量的参数的情况。

    命令实现的通常模式是首先解析参数,确定命令被要求执行的操作是否合理并且当事情不合理时返回错误(即,Tcl异常)。然后调用底层代码来实际执行真正的任务。最后,底层代码的结果 - 包括任何报告的失败 - 被转换回可以通过Tcl的形式。此模式非常常见。

  • Tcl_WrongNumArgs是在load DLL时将命令安装到Tcl中的代码。名称和签名都很重要;名称必须与计算的库名称匹配后缀Sample_Init(在这种情况下,我们期望被称为_Initsample.dll或类似的东西)。请注意,它会调用libsample.soTcl_InitStubsTcl_PkgProvideTcl_CreateObjCommand(或其相关功能之一)也是合理的,但这个包不会这样做。

编译指令往往会在平台之间略有不同,但如果您曾经在一个系统上构建了一个扩展DLL,那么其他系统实际上并没有那么不同。

将DLL转换为完整包然后需要在它旁边添加一点Tcl_SetVar,并且安装包会将这两个文件转储到正确的目录中(如果你正在做的话,可能正确设置权限)系统安装等)。你可以得到比这更复杂的东西,但这并不难。对于特定于应用程序的内容,您可以将DLL / package-index文件保存在您控制的目录中,并在执行pkgIndex.tcl之前扩展Tcl的auto_path全局变量。