0

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 ]
...
ms_stud
  • 361
  • 4
  • 18
  • Please be more specific. Exactly what is the error. Show us the code with what you are trying to do. It is unclear what you are asking here. And `@` doesn't invoke anything in either Tcl or C. – Brad Lanam Aug 25 '18 at 14:47
  • I'm trying to invoke my C wrap functions which I loaded through my .o file from procedure in tcl. 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. – ms_stud Aug 25 '18 at 15:13

1 Answers1

1

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:

  • Use two different Tcl namespaces, with same named procedures
  • Apply some naming conventions to wrapper procs and commands (your cFunc hint)
  • If your API were provided as actual Itcl or TclOO objects, and the individual commands were the methods, you could use a subclass or a mixin to host refinements (using the super-reference, such as next in TclOO, to forward from the scripted refinement to the C implementations).

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
}
mrcalvin
  • 3,291
  • 12
  • 18