ActiveState refer to tclkit and stardll as basekit and there is such a DLL included with ActiveTcl (base-tcl-thread-win32-ix86.dll on Windows).TclKit_SetKitPathThe tclkit initialization code expects to mount the executable to access the tclkit virtual filesystem. When you use tclkit as a shared library you must inform the initialization code that it must mount a different file. Therefore the very first call you make must be to TclKit_SetKitPath(const char *path) giving the filename and path of the shared library. Second must be a call to TclKit_AppInit(Tcl_Interp *interp) to initialize the runtime.
ExampleAn example of an application that embeds tcl using this technique follows.
/* tclembed.c - Copyright (C) 2003 Pat Thoyts <patthoyts@users.sourceforge.net>
*
* Sample of an embedded Tcl application linked using the Tcl stubs mechanism
* as seen at http://wiki.tcl.tk/2074.
*
* This version demonstrates linking to the stardll (ActiveTcl calls it a
* basekit DLL) which is a TclKit presented as a DLL.
*
* ----------------------------------------------------------------------
* This source code is public domain.
* ----------------------------------------------------------------------
*
* $Id$
*/
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifndef USE_TCL_STUBS
#define USE_TCL_STUBS
#endif
#include <tcl.h>
static Tcl_Interp *InitializeTcl(const char *dllname,int argc, char *args[]);
int
main(int argc, char *argv[])
{
Tcl_Interp *interp;
int r = TCL_OK;
interp = InitializeTcl("basekit.dll", argc, argv);
if (interp == NULL) {
fprintf(stderr, "error: failed to initialize Tcl runtime\n");
} else {
if (argc > 1) {
r = Tcl_EvalFile(interp, argv[1]);
printf(Tcl_GetStringResult(interp));
}
Tcl_DeleteInterp(interp);
}
return r;
}
typedef Tcl_Interp * (*LPFNCREATEINTERP) ();
typedef int (*LPFNBASEKITINIT) (Tcl_Interp *);
typedef char * (*LPFNSETKITPATH) (char *);
Tcl_Interp *
InitializeTcl(const char *dllname, int argc, char *argv[])
{
TCHAR szLibrary[MAX_PATH];
HINSTANCE hTcl = NULL;
Tcl_Interp *interp = NULL;
hTcl = LoadLibraryA(dllname);
if (hTcl != NULL) {
LPFNCREATEINTERP lpfnCreateInterp
= (LPFNCREATEINTERP)GetProcAddress(hTcl, "Tcl_CreateInterp");
LPFNBASEKITINIT lpfnBasekitInit
= (LPFNBASEKITINIT)GetProcAddress(hTcl, "TclKit_AppInit");
LPFNSETKITPATH lpfnSetKitPath
= (LPFNSETKITPATH)GetProcAddress(hTcl, "TclKit_SetKitPath");
if (lpfnCreateInterp != NULL && lpfnBasekitInit != NULL
&& lpfnSetKitPath != NULL)
{
interp = lpfnCreateInterp();
if (interp != NULL) {
Tcl_InitStubs(interp, "8.4", 0);
Tcl_FindExecutable(argv[0]);
GetModuleFileNameA(hTcl, szLibrary, MAX_PATH);
lpfnSetKitPath(szLibrary);
if (lpfnBasekitInit(interp) == TCL_OK) {
Tcl_InitMemory(interp);
} else {
fprintf(stderr, "TclKit_AppInit: %s\n",
Tcl_GetStringResult(interp));
}
}
}
}
return interp;
}
