'''Using Microsoft Visual C++ 6''' * Create a new win32 dynamic link library project and call it something nice, like ''tcldemo''. This is going to be our package name too. * Select an 'Empty DLL' on the next dialog. * Before you get going, make sure you have told Visual Studio about the Tcl headers and libraries. To do this, open Tools->Options->Directories and give the Tcl include directory in the includes box and the libraries in the libraries box. * Open up the Project settings menu item for your new project and go to the C++ tab. Add USE_TCL_STUBS to the list of defined symbols and in the Link tab prepend tclstub83.lib to the list of libraries. (Adust the numerical suffix for your version of tcl). * Now we can write some code. Create a new C++ source file, called tcldemo.cpp and paste in the code below. * Build it. Ignore the whining about MSCVRT conflicts. You now have a ''DLL'' in either Debug/Release. * Fire up tclsh or better tkcon from the Debug or Release subdirectory under your project and issue load tcldemo''dll'' Tcldemo set tcldemo_version package require Tcldemo * You should get 0.1 printed twice! '''Using mingw32 GNU C / C++''' If you don't happen to have a copy of Microsoft's compiler then you can get a copy of GNU C compiled for the win32 platform. The mingw32 project is the minimal approach which uses only the native libraries and so doesn't support unix porting much - see http://sourceforge.net/projects/mingw for the releases. * Create a .cpp or .cc file with the code below using your favourite editor. (eg: emacs) * Create a tcldemo.def file with the following lines: EXPORTS Tcldemo_Init Tcldemo_SafeInit * Compile the code: g++ -Wall -g -Ii:/opt/Tcl/include -c tcldemo.cpp -o tcldemo.o * Link the code. If you are using a standard distribution such as ActiveTcl then see [How to create mingw32 libraries from DLLs]: dllwrap --driver-name g++ -def tcldemo.def -o tcldemo.dll tcldemo.o -Li:/opt/Tcl/lib -ltcl83 -lm * Voila: you now have a tcldemo.dll. Test as above. I've included a suitable Makefile below. ---- '''The code:''' #include #include #ifndef DECLSPEC_EXPORT #define DECLSPEC_EXPORT __declspec(dllexport) #endif // DECLSPEC_EXPORT BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { return TRUE; } EXTERN_C int DECLSPEC_EXPORT Tcldemo_Init(Tcl_Interp* interp) { #ifdef USE_TCL_STUBS Tcl_InitStubs(interp, "8.3", 0); #endif Tcl_Obj *version = Tcl_SetVar2Ex(interp, "tcldemo_version", NULL, Tcl_NewDoubleObj(0.1), TCL_LEAVE_ERR_MSG); if (version == NULL) return TCL_ERROR; int r = Tcl_PkgProvide(interp, "Tcldemo", Tcl_GetString(version)); // Call Tcl_CreateObjCommand etc. return r; } EXTERN_C int DECLSPEC_EXPORT Tcldemo_SafeInit(Tcl_Interp* interp) { // We don't need to be specially safe so... return Tcldemo_Init(interp); } ---- # -*- Makefile -*- for Tcl Demo # # @(#)$Id: 2419,v 1.14 2002-06-21 04:00:41 jcw Exp $ CC =g++ DLLWRAP =dllwrap DLLTOOL =dlltool RM =rm -f CFLAGS =-Wall -Ii:/opt/tcl/include -DUSE_TCL_STUBS LDFLAGS =-Li:/opt/tcl/lib LIBS =-ltclstub83 DLL =tcldemo.dll DEFFILE =tcldemo.def WRAPFLAGS =--driver-name $(CC) --def $(DEFFILE) CSRCS =tcldemo.cpp OBJS =$(CSRCS:.cpp=.o) $(DLL): $(OBJS) $(DLLWRAP) $(WRAPFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) clean: $(RM) *.o core *~ %.o: %.cpp $(CC) $(CFLAGS) -c $< -o $@ .PHONY: clean # # Local variables: # mode: makefile # End: # ---- This excellent piece of work was created and put here by [Pat Thoyts]. Thanks Pat!