4

I am trying to create a simple c++ console app that calls the nagelfar syntax checker on a script. I followed the directions here: http://wiki.tcl.tk/19919 , adding the tclstub85.lib to my input, adding the tcl lib directory to my additional libraries, and adding my header directory as well. Linking fails with:

main.obj : error LNK2001: unresolved external symbol _tclStubsPtr 

This is my command line for linking:

/OUT:"C:\Users\######\Documents\Visual Studio 2005\Projects\Nagelfar\Release\Nagelfar.exe"
/NOLOGO /LIBPATH:"C:\Tcl\lib" /MANIFEST 
/MANIFESTFILE:"Release\Nagelfar.exe.intermediate.manifest" /DEBUG
/PDB:"c:\users\######\documents\visual studio 2005\projects\nagelfar\release\Nagelfar.pdb"
/OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT C:\Tcl\lib\tclstub85.lib
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 

This is the full source code, which I can compile and run fine in Linux using g++:

#include <stdlib.h>
#include <stdio.h>
#include <tcl.h>
#include <string.h>

Tcl_Interp * tcl_interp ;
char fileToCheck[] = "test.tcl";
char dbFile[] = "syntaxdb.tcl";

int main () {
    int code, argc;
    const char **argv;
    char command[1024];
    char *results = NULL; 
    tcl_interp = Tcl_CreateInterp();
    Tcl_SetVar2(tcl_interp, "::Nagelfar", "embedded", "1", 0);  
    code = Tcl_EvalFile(tcl_interp, "nagelfar.tcl"); 
    Tcl_LinkVar(tcl_interp, "::Nagelfar(chkResult)", (char *)&results, TCL_LINK_STRING); 
    sprintf(command, "synCheck %s %s", fileToCheck, dbFile); 
    code = Tcl_Eval(tcl_interp, command);
    printf("Raw Result: \r\n %s\r\n", results); 
    code = Tcl_SplitList(tcl_interp, results, &argc, &argv); 
    {
        int i;
        for (i = 0; i < argc; ++i)
        {
            printf("%d/%d: %s\r\n", i+1, argc, argv[i]); 
        }
    }
    Tcl_Free(results);
    return 0;
}

Solved my own problem: I had x64 ActiveTcl but was linking a 32 bit project. Using the x86 ActiveTcl distribution fixed my issues.

bodangly
  • 2,473
  • 17
  • 28

2 Answers2

1

Your error message tells us that you are expecting a stub table (Tcl's goes by the name tclStubPtr once all the macros are expanded), which in turn says that defining the preprocessor symbol USE_TCL_STUBS. That symbol is for use in the case where you are writing a library that is providing extra functionality to Tcl. However, in the case where you are writing a main application that calls functions in the Tcl library — such as “run this code” — you can't (easily) use the stubs mechanism as you'd be needing the stub table before Tcl is in a position to be able to provide it to you.

The fix is to not define USE_TCL_STUBS and to link against the main Tcl library (probably C:\Tcl\lib\tcl85.dll on your system) instead of tclstub85.lib. (I don't know enough about setting up Visual Studio to say what the details of that configuration are.)


You should also add this line to your code before the call to Tcl_CreateInterp():

Tcl_FindExecutable(NULL);

That call is used to allow the Tcl library core to initialize itself, doing little things like getting the memory manager and filesystem interface layer working.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Thank you, I did discover I was not supposed to use the stubs, but the root of my issue was I had downloaded a 64 bit Tcl library but had a 32 bit project. – bodangly Nov 16 '12 at 15:21
  • @user Oooh yes, that wouldn't work. (Stubs is a great tech, but it doesn't try to solve all problems. That's a good thing really, as it is better to do one thing well than many things badly. :-)) – Donal Fellows Nov 17 '12 at 20:58
1

Solved my own problem: I had x64 ActiveTcl but was linking a 32 bit project. Using the x86 ActiveTcl distribution fixed my issues.

bodangly
  • 2,473
  • 17
  • 28