ratchet
ratchet

Reputation: 3

how to link to the tclOO functions in the Tcl C API

As a short example of what I can't do:

#include <tcl.h>
#include <tclOO.h>

int main(void) {
    Tcl_Interp *interp = Tcl_CreateInterp();
    Tcl_Obj *obj = Tcl_NewStringObj("myObject", -1);
    Tcl_Object object = Tcl_GetObjectFromObj(interp, obj);
    return 0;
}

Then compiling with:

gcc main.c -o tclOOTest -ltcl

I of course get an error from the linker because I'm not linking against a library that has a definition for Tcl_GetObjectFromObj. Trouble is I don't know what library to link against. I thought tclOO was built into tcl since 8.6 (which is what I'm using).

Here is the error:

/tmp/ccZnpdY8.o: In function `main':
main.c:(.text+0x33): undefined reference to `Tcl_GetObjectFromObj'
collect2: error: ld returned 1 exit status

Upvotes: 0

Views: 143

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137627

The TclOO API, unlike much of the rest of Tcl, only exports itself via a stubs table. You should #define the symbol USE_TCL_STUBS to be 1 before you #include the Tcl header file, and link against the tclstub library. (This is the recommended way of building extensions anyway.)

[EDIT]: If you're embedding Tcl within your program, you need a more complex procedure. Basically, you need to partition your program into the parts that are an application and the parts that are an internal extension. The parts that call Tcl_CreateInterp are most likely the application part, and the parts that access the TclOO API are the extension (and will need to call Tcl_InitStubs and Tcl_OOInitStubs in an initialisation function).

The extension parts need to be compiled with USE_TCL_STUBS defined. (As it is critical, you might put that as a #define at the top of the file. The wiki page mentions USE_TCLOO_STUBS as well, but that's implied by USE_TCL_STUBS.) The extension parts need to be built without it. You can call the initialisation function that installs your internal extension immediately after the Tcl_CreateInterp call, before you start running any (non-built-in) scripts. Then when you link everything you link both against libtclstub and libtcl.

The reason for this complexity is that TclOO started out as a separate extension itself, and that never supported external API references. I probably ought to relax those restrictions for Tcl 8.7…

Upvotes: 2

Related Questions