apitclitcl

invoking TCL C API's inside tcl package procedures


I am using TCL-C API for my program.
and I read and created test program that is similar to this C++ example.
But I have a problem with this example. when I use this example in the shell (by loading it with load example.o) every input automatically invokes the interpreter of the API and run the command that is related to the input string.
But suppose that I want that the input will invoke tcl procedure that is inside a package required by me , this procedure will check the parameters and will print another message and only after this will invoke TCL-C API related function (kind of wrapper), In this case how can I do it?
I read somewhere that the symbol @ is the symbol should be used for invoking external program but I just can't find where it was.
I will give a small example for make things more clear.

somepackage.tcl

proc dosomething { arg1 , arg2 , arg3 } {
   # check args here #
   set temp [ #invoke here TCL-C API function and set it's result in temp ]
   return $temp
}

package provide ::somepackage 1.0  

test.tcl

package require ::somepackage 1.0
load somefile.o   # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...

Solution

  • But I have a problem with this example. when I use this example in the shell (by loading it with load example.o) every input automatically invokes the interpreter of the API and run the command that is related to the input string.

    Provided that you script snippets represent your actual implementation in an accurate manner, then the problem is that your Tcl proc named doSomething is replaced by the C-implemented Tcl command once your extension is loaded. Procedures and commands live in the same namespace(s). When the loading order were reversed, the problem would remain the same.

    I read that everything is being evaluated by the tcl interperter so in this case I should name the tcl name of the C wrap functions in special way for example cFunc. But I am not sure about this.

    This is correct. You have to organise the C-implemented commands and their scripted wrappers in a way that their names do not conflict with one another. Some (basic) options:

    A hot-fix solution in your current setup, which is better replaced by some actual design, would be to rename or interp hide the conflicting commands:

    1. load somefile.o
    2. Hide the now available commands: interp hide {} doSomething
    3. Define a scripted wrapper, calling the hidden original at some point:

    For example:

    proc doSomething {args} {
      # argument checking
      set temp [interp invokehidden {} doSomething {*}$args]
      # result checking
      return $temp
    }