Use tcl and tk in C program

I need a simple C program that creates a tcl interpreter, initializes tcl and tk, and then loads the given tcl / tk script. I want to use tcl and tk stubs (so that the program runs on a computer with a different version of tcl / tk). I will use this program instead of launching desire (because I have portability problems).

#include <stdio.h> #include <stdlib.h> #include <tcl.h> #include <tk.h> int AppInit(Tcl_Interp *interp) { if(Tcl_Init(interp) == TCL_ERROR) return TCL_ERROR; if(Tk_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_EvalFile(interp,"myscript.tcl"); return TCL_OK; } int main(int argc, char *argv[]) { Tk_Main(argc, argv, AppInit); return 0; } 

I tried to compile (on GNU / Linux) the following command. The program compiles without errors, but then stops with a segmentation error.

 gcc -I/usr/include/tcl8.5 -DUSE_TCL_STUBS -DUSE_TK_STUBS -o main.exe ../main.c /usr/lib/libtclstub.a /usr/lib/libtkstub.a 
+3
c tcl
source share
1 answer

TL; DR

When compiling a program with main you should not use stubs. Instead, building without USE_TCL_STUBS and USE_TK_STUBS defines and associates with libtcl.so and libtk.so (well, with any version number that was attached to them). Due to the nature of the Unix linker, you must place the Tk library in front of the Tcl library (and you may also need to manually link to other libraries as well, such as the X library, sometimes this is due to black art).

Justification

The stubs mechanism is designed so that the Tcl extension library can use the Ccl (and Tk) C API without binding itself to the Tcl library itself. This means that the library does not depend on what exact version of Tcl is present during its loading, but simply depends on the specific version of the Tcl API (Tcl is pretty good at managing long-term APIs and ABI compatibility). However, all this depends on the initialization function of the library, called using a special kind of pointer, which allows you to view all other API functions. (Once Tcl has been loaded this way, itโ€™s much easier to find all the other APIs.) When you create the application, as you do, the problem is that there is no existing boot instance of the Tcl library for your code to link to; it must be connected directly (and in fact, both Tcl_Main and Tk_Main are disjoint functions for this exact reason).

Those of you who read at home might think that this Tcl repeats a lot of what the dynamic linker does. You would be right. However, the system dynamic linker has a number of ways that it may not do quite correctly (for example, it can become very confused if there are several versions of the library), and it subtly changes in its capabilities between platforms. Tcl uses its own mechanism because it does the job exactly (for Tcl) everywhere, giving us much better control over long-term ABI compatibility.

There is an exception to the stub rule above, and this is tclkit , which is the full runtime of Tcl and Tk (plus a small NoSQL database) in a single file. The bootstrap code for tclkit is terribly complicated; you donโ€™t want to deal with things that you donโ€™t need! If you want to use the single-page Tcl environment, you use tclkit (or one of the few other systems that do almost equivalent things).

+3
source share

All Articles