使用Tcl_CreateMathFunc在TCL中定义新的数学函数

时间:2012-06-16 12:02:58

标签: math tcl

我使用TCL 8.4,对于该版本,我需要使用TCL库函数将新的数学函数添加到TCL解释器中,尤其是Tcl_CreateMathFunc。但我找不到一个如何做到的例子。请你能为我写一个非常简单的例子,假设在C代码中你有一个Tcl_Interp *interp你应该添加一个数学函数(比如,一个乘以两个双数的函数)。

2 个答案:

答案 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将其写成类型灵活 - 只允许在注册/声明中 - 使事情变得复杂得多,并且你真的陷入固定的参数计数。)