David Gravereaux gave this code on news:comp.lang.tcl for writing code which will compile for both stubs-enabled, and pre-stubs (8.0) Tcl, both using the Tcl_Obj interface (so nothing prior to 8.0). Perhaps people can add extras for different compilers/platforms... 8.0 and 8.1+ have a different interface for extensions. Please pardon the overdose of macros, but this works and is very aggressive: #include // We need at least the Tcl_Obj interface that was started in 8.0 #if TCL_MAJOR_VERSION < 8 # error "we need Tcl 8.0 or greater to build this" // Check for Stubs compatibility when asked for it. #elif defined(USE_TCL_STUBS) && TCL_MAJOR_VERSION == 8 && \ (TCL_MINOR_VERSION == 0 || \ (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL != TCL_FINAL_RELEASE)) # error "Stubs interface doesn't work in 8.0 and alpha/beta 8.1; only 8.1.0+" #endif #ifdef _MSC_VER // Only do this when MSVC++ is compiling us. # ifdef USE_TCL_STUBS // Mark this .obj as needing tcl's Stubs library. # pragma comment(lib, "tclstub" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # if !defined(_MT) || !defined(_DLL) || defined(_DEBUG) // This fixes a bug with how the Stubs library was compiled. // The requirement for msvcrt.lib from tclstubXX.lib should // be removed. # pragma comment(linker, "-nodefaultlib:msvcrt.lib") # endif # else // Mark this .obj needing the import library # pragma comment(lib, "tcl" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # endif #endif #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT EXTERN int Livemsg_Init(Tcl_Interp *interp) { int code; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif Tcl_CreateObjCommand(interp,"LiveMsg",LiveMsgObjCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); code=Tcl_PkgProvide(interp,"LiveMsg","1.0"); if (code != TCL_OK) { return code; } // init here return TCL_OK; } ---- Also see "[How to write C-coded extensions for Tcl]". and http://www.tcl-tk.net/doc/howoto/stubs.html