Search code examples
ctclwrapper

How to make callbacks from C code to Tcl that returns data to C


I faced with the issue - I have C code of optimization library, and it accepts pointer to function as one of the argument. So, previously I used SWIG to generate Tcl wrapper of for C functions, but in this case I need to call Tcl function from C. Each time callback is invoked, it calculates the values of the functions with particular parameters as its arguments. I want to call Tcl procedure for that, and it should be done inside the same interpreter I call the C optimization procedure, and then return data back to C program.

I found that it is not possible with SWIG without modifying C source code and some typemaps hacks. What are the other options? I checked Critcl, but there I again have to modify and reorder C source code. The only viable option I see now is direct use of Tcl C API. Are there any other ways to accomplish that? Thank you.


Solution

  • The best way to call a Tcl command from C is the API function Tcl_EvalObjv(). You need an interpreter context to call that, and the command name and other arguments to the command are passed in an array of Tcl_Obj* handles (the box type that contains all Tcl values). This method of calling has the lowest overheads, but values passed must have a non-zero reference count (i.e., call Tcl_IncrRefCount on them before and Tcl_DecrRefCountafterwards).

    Otherwise, build a string and call Tcl_Eval() (or a Tcl value and call Tcl_EvalObj()). These incur additional overheads, such as needing to parse the string.

    You can manufacture Tcl_Obj* handles using calls such as Tcl_NewIntObj() or Tcl_ObjPrintf().

    See https://www.tcl-lang.org/man/tcl8.6/TclLib/Eval.htm for more options for calling commands from C.