'''[http://www.swig.org/%|%SWIG]''', or '''Simplified Wrapper and Interface Generator''', by [Dave Beazley], generates Tcl [C] interfaces [C] and [C++] code. ** Attributes ** name: SWIG website: http://www.swig.org/ latest version: 3.0.5 ** See Also ** [Swig example showing access to C structures from Tcl]: [Generating wrappers for C and Fortran]: ** Documentation ** [http://www.tldp.org/LDP/LGNET/issue49/pramode.html%|%Using SWIG to interface scripting languages with C/C++] ([https://web.archive.org/web/20060222044235/http://www.linuxgazette.com/issue49/pramode.html%|%alternate]), Pramode C.E. and Gopakumar C.E, 2000: [http://www.swig.org/papers/Tcl98/TclChap.html%|%Tcl and SWIG as a C/C++ Development Tool], [David Beazley], 1998: [http://www.drdobbs.com/open-source/swig-and-automated-cc-scripting-extensio/184410484?queryText=beazley%2Bswig%|%SWIG Extends Scripting Languages], [David Beazley], [http://www.drdobbs.com/%|%Dr.Dobb's], 1998-02-01: [http://wfr.tcl.tk/1693%|%SWIG Examples]: ** Description ** '''SWIG''' automates the generation of interfaces in various languages, including Tcl, to functions written in [C]/[C++]. SWIG reads ANSI C/C++ declarations and builds a an interface in the target language. SWIG is avalable for [Unix%|%Unix]-like systems and also for [Microsoft Windows%|%Windows] The idea of Swig is to provide a tool that can, with hopefully little pain, allow one to create glue code between general libraries and various scripting languages, one of which is [Tcl]. Swig can be used for C++ or C libraries - making it one of the first places people are recommended to look when dealing with legacy libraries. Benefits and uses of SWIG: * Rapidly prototype new features. * Interactively debug and test your code. * Develop a graphical user interface. * Saves lots of time--allowing you to work on the real problem. To contrast SWIG with [Objectify] - SWIG has you prepare a small interface file that specifies what functions are to be wrapped, rather than adding macros to your original header file. It also works with C, as well as C++. If you look around in books or places like [Cameron Laird]'s Tcl pages [http://phaseit.net/claird/comp.lang.tcl/] you can find a lot of information about integrating Tcl with C. That's all fine and dandy if you're going to write the interface code by hand. But if you want a nice example of how you ''ought'' to write your wrappers to call C or C++ from Tcl, then you can't go wrong looking at the code generated by SWIG. [David Beazley] did a great job of implementing both the old Tcl 7.x all-string interface and the Tcl 8.x object interface. Modern versions of SWIG (since 1.3a5) do not support the Tcl 7.x interface. For example, a short little function like this: ======c double convert ( int *value, char *targetUnits ); ====== gets wrapped by SWIG with this code for Tcl 8.x: ======c static int _wrap_convert(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { double _result; int * _arg0; char * _arg1; Tcl_Obj * tcl_result; char * rettype; int templength; clientData = clientData; objv = objv; tcl_result = Tcl_GetObjResult(interp); if ((objc < 3) || (objc > 3)) { Tcl_SetStringObj(tcl_result,"Wrong # args. convert value targetUnits ",-1); return TCL_ERROR; } if ((rettype = SWIG_GetPointerObj(interp,objv[1],(void **) &_arg0,"_int_p"))) { Tcl_SetStringObj(tcl_result, "Type error in argument 1 of convert. Expected _int_p, received ", -1); Tcl_AppendToObj(tcl_result, rettype, -1); return TCL_ERROR; } if ((_arg1 = Tcl_GetStringFromObj(objv[2], &templength)) == NULL) return TCL_ERROR; _result = (double )convert(_arg0,_arg1); tcl_result = Tcl_GetObjResult(interp); Tcl_SetDoubleObj(tcl_result,(double) _result); return TCL_OK; } ====== If you're using SWIG 1.1 or earlier, it also supported the 7.x interface model: ======c static int _wrap_convert(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { double _result; int * _arg0; char * _arg1; clientData = clientData; argv = argv; if ((argc < 3) || (argc > 3)) { Tcl_SetResult(interp, "Wrong # args. convert value targetUnits ",TCL_STATIC); return TCL_ERROR; } if (SWIG_GetPtr(argv[1],(void **) &_arg0,"_int_p")) { Tcl_SetResult(interp, "Type error in argument 1 of convert. Expected _int_p, received ", TCL_STATIC); Tcl_AppendResult(interp, argv[1], (char *) NULL); return TCL_ERROR; } _arg1 = argv[2]; _result = (double )convert(_arg0,_arg1); Tcl_PrintDouble(interp,(double) _result, interp->result); return TCL_OK; } ====== ---- As of SWIG 1.3.40, the generated C/C++ wrapper will use the [Stubs] feature if compiled with -DUSE_TK_STUBS. Also, you can override the minimum version to support which is passed to Tcl_InitStubs() and Tk_InitStubs() with -DSWIG_TCL_STUBS_VERSION="8.3" or the version being compiled with using -DSWIG_TCL_STUBS_VERSION=TCL_VERSION. ---- [AMG]: I'd like the ability to `[unload]` a Swig extension, but the latest CVS only provides xxx_Init() and xxx_SafeInit(). Any suggestions? ---- 2011-04-13: David Beazley: "... life is too short to wrap my brain around the ever-growing pile of hacks called [C++]. ... things like this are why I don't work on swig anymore." <> Application | C | C++