Posted to tcl by patthoyts at Wed Apr 08 14:10:37 GMT 2009view raw
- /* basethrd.c - Copyright (C) 2009 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 will create two threads and load a given basekit dll library on
- * each.
- *
- * can be built using:
- * cl -MD -W3 -I/opt/tcl/include basethrd.c \opt\tcl\lib\tclstub85.lib
- *
- * ----------------------------------------------------------------------
- * 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[]);
- typedef struct Init {
- const char *path;
- int argc;
- char **argv;
- DWORD tid;
- } Init;
- DWORD WINAPI
- BeginThread(LPVOID pClientData)
- {
- Init *pInit = pClientData;
- Tcl_Interp *interp;
- int r = TCL_OK;
- interp = InitializeTcl(pInit->path, pInit->argc, pInit->argv);
- if (interp == NULL) {
- fprintf(stderr, "error: failed to initialize Tcl\n");
- } else {
- if (pInit->argc > 1) {
- r = Tcl_EvalFile(interp, pInit->argv[1]);
- printf(Tcl_GetStringResult(interp));
- }
- Tcl_DeleteInterp(interp);
- }
- return r;
- }
- int
- main(int argc, char *argv[])
- {
- HANDLE threads[2];
- Init init[2];
- int n;
- init[0].path = "basekit.dll";
- init[1].path = "basekit85.dll";
- for (n = 0; n < sizeof(threads)/sizeof(threads[0]); ++n)
- {
- init[n].argc = argc;
- init[n].argv = argv;
- threads[n] = CreateThread(0, 0, BeginThread, &init[n],
- CREATE_SUSPENDED, &init[n].tid);
- }
- /* start the threads */
- for (n = 0; n < sizeof(threads)/sizeof(threads[0]); ++n)
- ResumeThread(threads[n]);
- while (1)
- {
- DWORD dwWait = WaitForMultipleObjects(n, threads, TRUE, 1000);
- if (dwWait == WAIT_TIMEOUT) {
- printf("tick\n");
- } else if (dwWait >= WAIT_OBJECT_0 && dwWait < (WAIT_OBJECT_0 + n)) {
- break;
- } else {
- fprintf(stderr, "error!\n");
- break;
- }
- }
- /* cleanup politely */
- for (n = 0; n < sizeof(threads)/sizeof(threads[0]); ++n)
- CloseHandle(threads[n]);
- return 0;
- }
- typedef Tcl_Interp * (*LPFNCREATEINTERP) ();
- typedef int (*LPFNBASEKITINIT) (Tcl_Interp *);
- typedef char * (*LPFNSETKITPATH) (char *);
- Tcl_Interp *
- InitializeTcl(const char *dllname, int argc, char *argv[])
- {
- WCHAR szLibrary[MAX_PATH];
- CHAR utfLibrary[MAX_PATH * 2];
- 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]);
- GetModuleFileNameW(hTcl, szLibrary, MAX_PATH);
- WideCharToMultiByte(CP_UTF8, 0, szLibrary, -1, utfLibrary, MAX_PATH*2, NULL, NULL);
- lpfnSetKitPath(utfLibrary);
- if (lpfnBasekitInit(interp) == TCL_OK) {
- Tcl_InitMemory(interp);
- } else {
- fprintf(stderr, "TclKit_AppInit: %s\n",
- Tcl_GetStringResult(interp));
- }
- }
- }
- }
- return interp;
- }