我使用TCL 8.4,对于该版本,我需要使用TCL库函数将新的数学函数添加到TCL解释器中,尤其是Tcl_CreateMathFunc
。但我找不到一个如何做到的例子。请你能为我写一个非常简单的例子,假设在C代码中你有一个Tcl_Interp *interp
你应该添加一个数学函数(比如,一个乘以两个双数的函数)。
答案 0 :(得分:3)
我曾经为Tcl做过随机数生成器的一些替代实现,你可以看一下git repository的一些例子。泛型文件为每个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;
}
答案 1 :(得分:2)
请注意,这是一个不太可能无限期生存的API(原因包括其奇怪的类型,不灵活的参数处理以及无法从Tcl本身轻松使用它)。但是,这里是如何使用add(x,y)
s:
double
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
将其写成类型灵活 - 只允许在注册/声明中 - 使事情变得复杂得多,并且你真的陷入固定的参数计数。)