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;
- }