我使用 TCL 8.4,对于该版本,我需要使用 TCL 库函数将新的数学函数添加到 TCL 解释器中,特别是Tcl_CreateMathFunc
. 但我找不到一个如何做到这一点的例子。请你为我写一个非常简单的例子,假设在 C 代码中你有一个Tcl_Interp *interp
你应该添加一个数学函数(比如,一个将两个双数相乘的函数)。
问问题
371 次
2 回答
3
我曾经为 Tcl 做过一些随机数生成器的替代实现,您可以在git 存储库中查看一些示例。generic 中的文件为每个 PRNG 实现一个 tcl 命令和一个 tcl 数学函数。
因此,例如在 Mersenne Twister 实现中,在包 init 函数中,我们通过声明将新函数添加到解释器
Tcl_CreateMathFunc(interp, "mt_rand", 1, (Tcl_ValueType *)NULL, RandProc, (ClientData)state);
这为我们注册了 C 函数 RandProc。在这种情况下,该函数不接受任何参数,但种子等效项 (srand) 显示了如何处理单个参数。
/*
* A Tcl math function that implements rand() using the Mersenne Twister
* Pseudo-random number generator.
*/
static int
RandProc(ClientData clientData, Tcl_Interp *interp, Tcl_Value *args, Tcl_Value *resultPtr)
{
State * state = (State *)clientData;
if (! (state->flags & Initialized)) {
unsigned long seed;
/* This is based upon the standard Tcl rand() initializer */
seed = time(NULL) + ((long)Tcl_GetCurrentThread()<<12);
InitState(state, seed);
}
resultPtr->type = TCL_DOUBLE;
resultPtr->doubleValue = RandomDouble(state);
return TCL_OK;
}
于 2012-06-16T13:07:55.053 回答
2
请注意,这是一个不太可能无限期存在的 API(原因包括其怪异的类型、不灵活的参数处理以及无法从 Tcl 本身轻松使用它)。但是,以下是如何在add(x,y)
两个参数都为double
s 的情况下执行操作:
登记
Tcl_ValueType types[2] = { TCL_DOUBLE, TCL_DOUBLE };
Tcl_CreateMathFunc(interp, "add", 2, types, AddFunc, NULL);
执行
static int AddFunc(ClientData ignored, Tcl_Interp *interp,
Tcl_Value *args, Tcl_Value *resultPtr) {
double x = args[0].doubleValue;
double y = args[1].doubleValue;
resultPtr->doubleValue = x + y;
resultPtr->type = TCL_DOUBLE;
return TCL_OK;
}
请注意,由于此 API 始终使用固定数量的函数参数(并为您处理参数类型转换),因此您编写的代码可能非常短。(把它写成类型灵活TCL_EITHER
——只允许在注册/声明中——使事情变得相当复杂,而且你真的被固定的参数数量所困扰。)
于 2012-06-16T18:06:01.253 回答