`Proceedings of the Fourth USENIX Tcl/Tk Workshop
`Monterey, CA, July 10-13, 1996
`
`SWIG : An Easy to Use Tool For Integrating
`Scripting Languages with C and C++
`
`David M. Beazley
`University of Utah
`Salt Lake City, Utah 84112
`
`For more information about USENIX Association contact:
`1. Phone:
`510 528-8649
`2. FAX:
`510 548-5738
`3. Email:
`office@usenix.org
`4. WWW URL: http://www.usenix.org
`
`Juniper Ex. 1019-p. 1
`Juniper v Finjan
`
`
`
`SWIG (cid:2) An Easy to Use Tool for Integrating Scripting Languages
`with C and C(cid:3)(cid:3)
`
`David M(cid:2) Beazley
`Department of Computer Science
`University of Utah
`Salt Lake City(cid:2) Utah
`beazley(cid:7)cs(cid:8)utah(cid:8)edu
`
`Abstract
`
`I present SWIG (cid:2)Simpli(cid:3)ed Wrapper and Interface
`Generator(cid:4)(cid:5) a program development tool that au(cid:6)
`tomatically generates the bindings between C(cid:7)C(cid:8)(cid:8)
`code and common scripting languages including Tcl(cid:5)
`Python(cid:5) Perl and Guile(cid:9)
`SWIG supports most
`C(cid:7)C(cid:8)(cid:8) datatypes including pointers(cid:5) structures(cid:5)
`and classes(cid:9) Unlike many other approaches(cid:5) SWIG
`uses ANSI C(cid:7)C(cid:8)(cid:8) declarations and requires the
`user to make virtually no modi(cid:3)cations to the un(cid:6)
`derlying C code(cid:9)
`In addition(cid:5) SWIG automati(cid:6)
`cally produces documentation in HTML(cid:5) LaTeX(cid:5) or
`ASCII format(cid:9) SWIG has been primarily designed
`for scientists(cid:5) engineers(cid:5) and application developers
`who would like to use scripting languages with their
`C(cid:7)C(cid:8)(cid:8) programs without worrying about the un(cid:6)
`derlying implementation details of each language or
`using a complicated software development tool(cid:9) This
`paper concentrates on SWIG(cid:10)s use with Tcl(cid:7)Tk(cid:9)
`
` Introduction
`
`SWIG (cid:2)Simpli(cid:3)ed Wrapper and Interface Genera(cid:4)
`tor(cid:5) is a software development tool that I never in(cid:4)
`tended to develop(cid:6) At the time(cid:7) I was trying to
`add a data analysis and visualization capability to
`a molecular dynamics (cid:2)MD(cid:5) code I had helped de(cid:4)
`velop for massively parallel supercomputers at Los
`Alamos National Laboratory (cid:8)Beazley(cid:7) Lomdahl(cid:9)(cid:6) I
`wanted to provide a simple(cid:7) yet (cid:10)exible user inter(cid:4)
`face that could be used to glue various code mod(cid:4)
`ules together and an extensible scripting language
`seemed like an ideal solution(cid:6) Unfortunately there
`were constraints(cid:6) First(cid:7) I didn(cid:11)t want to hack up
`(cid:4)years of code development trying to (cid:3)t our MD
`code into yet another interface scheme (cid:2)having done
`so several times already(cid:5)(cid:6) Secondly(cid:7) this code was
`routinely run on systems ranging from Connection
`
`Machines and Crays to workstations and I didn(cid:11)t
`want to depend on any one interface language(cid:13)out
`of fear that it might not be supported on all of these
`platforms(cid:6) Finally(cid:7) the users were constantly adding
`new code and making modi(cid:3)cations(cid:6) I needed a (cid:10)ex(cid:4)
`ible(cid:7) yet easy to use system that did not get in the
`way of the physicists(cid:6)
`
`Simply
`SWIG is my solution to this problem(cid:6)
`stated(cid:7) SWIG automatically generates all of the
`code needed to bind C(cid:14)C(cid:15)(cid:15) functions with script(cid:4)
`ing languages using only a simple input (cid:3)le con(cid:4)
`taining C function and variable declarations(cid:6) At
`(cid:3)rst(cid:7) I supported a scripting language I had devel(cid:4)
`oped speci(cid:3)cally for use on massively parallel sys(cid:4)
`tems(cid:6) Later I decided to rewrite SWIG in C(cid:15)(cid:15) and
`extend it to support Tcl(cid:7) Python(cid:7) Perl(cid:7) Guile and
`other languages that interested me(cid:6)
`I also added
`more data(cid:4)types(cid:7) support for pointers(cid:7) C(cid:15)(cid:15) classes(cid:7)
`documentation generation(cid:7) and a few other features(cid:6)
`
`This paper provides a brief overview of SWIG with a
`particular emphasis on Tcl(cid:14)Tk(cid:6) However(cid:7) the reader
`should remain aware that SWIG works equally well
`with Perl and other languages(cid:6) It is not my intent
`to provide a tutorial or a user(cid:11)s guide(cid:7) but rather to
`show how SWIG can be used to do interesting things
`such as adding Tcl(cid:14)Tk interfaces to existing C appli(cid:4)
`cations(cid:7) quickly debugging and prototyping C code(cid:7)
`and building interface(cid:4)language(cid:4)independent C ap(cid:4)
`plications(cid:6)
`
` Tcl and Wrapper Functions
`
`In order to add a new C or C(cid:15)(cid:15) function to Tcl(cid:7) it is
`necessary to write a special (cid:16)wrapper(cid:17) function that
`parses the function arguments presented as ASCII
`strings by the Tcl interpreter into a representation
`that can be used to call the C function(cid:6) For example(cid:7)
`
`Juniper Ex. 1019-p. 2
`Juniper v Finjan
`
`
`
`Input File
`
`SWIG
`
`Parser
`
`Code
`Generator
`
`Doc.
`Module
`
`Tcl
`Perl
`Guile
`
`ASCII
`LaTeX
`HTML
`
`Figure (cid:18) SWIG organization(cid:6)
`
`also aims to simplify code development (cid:8)ET(cid:9)(cid:6) Un(cid:4)
`like ET(cid:7) SWIG is designed to integrate C functions
`into Tcl(cid:14)Tk as opposed to integrating Tcl(cid:14)Tk into
`C programs(cid:6)
`
` A Quick Tour of SWIG
`
`(cid:3) Organization
`
`Figure shows the structure of SWIG(cid:6) At the core
`is a YACC parser for reading input (cid:3)les along with
`some utility functions(cid:6) To generate code(cid:7) the parser
`calls about a dozen functions from a generic lan(cid:4)
`guage class to do things like write a wrapper func(cid:4)
`tion(cid:7) link a variable(cid:7) wrap a C(cid:15)(cid:15) member func(cid:4)
`tion(cid:7) etc(cid:6)(cid:6)(cid:6) Each target language is implemented as
`a C(cid:15)(cid:15) class containing the functions that emit the
`resulting C code(cid:6) If an (cid:16)empty(cid:17) language de(cid:3)nition
`is given to SWIG(cid:7) it will produce no output(cid:6) Thus(cid:7)
`each language class can be implemented in almost
`any manner(cid:6) The documentation system is imple(cid:4)
`mented in a similar manner and can currently pro(cid:4)
`duce ASCII(cid:7) LaTeX(cid:7) or HTML output(cid:6) As output(cid:7)
`SWIG produces a C (cid:3)le that should be compiled
`and linked with the rest of the code and a docu(cid:4)
`mentation (cid:3)le that can be used for later reference(cid:6)
`
`(cid:3) Interface Files
`
`As input(cid:7) SWIG takes a single input (cid:3)le referred to
`as an (cid:16)interface (cid:3)le(cid:6)(cid:17) This (cid:3)le contains a few SWIG
`speci(cid:3)c directives(cid:7) but otherwise contains ANSI C
`function and variable declarations(cid:6) Unlike the ap(cid:4)
`proach in (cid:8)Heidrich(cid:9)(cid:7) no type conversion rules are
`needed and all declarations are made using famil(cid:4)
`iar ANSI C(cid:14)C(cid:15)(cid:15) prototypes(cid:6) The following code
`
`if you wanted to add the factorial function to Tcl(cid:7) a
`wrapper function might look like the following (cid:18)
`
`int wrap(cid:2)fact(cid:3)ClientData clientData(cid:4)
`Tcl(cid:2)Interp (cid:5)interp(cid:4)
`int argc(cid:4) char (cid:5)argv(cid:6)(cid:7)(cid:8) (cid:9)
`int result(cid:10)
`int arg (cid:10)
`if (cid:3)argc (cid:12)(cid:13) (cid:8) (cid:9)
`interp(cid:15)(cid:16)result (cid:13) (cid:17)wrong (cid:18) args(cid:17)(cid:10)
`return TCL(cid:2)ERROR(cid:10)
`
`(cid:19) a
`
`rg (cid:13) atoi(cid:3)argv(cid:6) (cid:7)(cid:8)(cid:10)
`result (cid:13) fact(cid:3)arg (cid:8)(cid:10)
`sprintf(cid:3)interp(cid:15)(cid:16)result(cid:4)(cid:17)(cid:21)d(cid:17)(cid:4)result(cid:8)(cid:10)
`return TCL(cid:2)OK(cid:10)
`
`(cid:19) I
`
`n addition to writing the wrapper function(cid:7) a user
`will also need to write code to add this function
`to the Tcl interpreter(cid:6) In the case of Tcl (cid:6)(cid:7) this
`could be done by writing an initialization function
`to be called when the extension is loaded dynami(cid:4)
`cally(cid:6) While writing a wrapper function usually is
`not too di(cid:21)cult(cid:7) the process quickly becomes te(cid:4)
`dious and error prone as the number of functions
`increases(cid:6) Therefore(cid:7) automated approaches for pro(cid:4)
`ducing wrapper functions are appealing(cid:22)especially
`when working with a large number of C functions
`or with C(cid:15)(cid:15) (cid:2)in which case the wrapper code tends
`to get more complicated(cid:5)(cid:6)
`
` Prior Work
`
`The idea of automatically generating wrapper code
`is certainly not new(cid:6) Some e(cid:23)orts such as Itcl(cid:15)(cid:15)(cid:7)
`Object Tcl(cid:7) or the XS language included with Perl(cid:7)
`provide a mechanism for generating wrapper code(cid:7)
`but require the user to provide detailed speci(cid:3)ca(cid:4)
`tions(cid:7) type conversion rules(cid:7) or use a specialized
`syntax (cid:8)Heidrich(cid:7) Wetherall(cid:7) Perl(cid:9)(cid:6) Large packages
`such as the Visualization Toolkit (cid:2)vtk(cid:5) may use their
`own C(cid:14)C(cid:15)(cid:15) translators(cid:7) but these almost always
`tend to be somewhat special purpose (cid:2)in fact(cid:7) SWIG
`started out in this manner(cid:5) (cid:8)vtk(cid:9)(cid:6) If supporting mul(cid:4)
`tiple languages is the ultimate goal(cid:7) a programmer
`might consider a package such as ILU (cid:8)Janssen(cid:9)(cid:6) Un(cid:4)
`fortunately(cid:7) this requires the user to provide speci(cid:4)
`(cid:3)cations in IDL(cid:22)a process which is unappealing to
`many users(cid:6) SWIG is not necessarily intended to
`compete with these approaches(cid:7) but rather is de(cid:4)
`signed to be a no(cid:4)nonsense tool that scientists and
`engineers can use to easily add Tcl and other script(cid:4)
`ing languages to their own applications(cid:6) SWIG is
`also very di(cid:23)erent than Embedded Tk (cid:2)ET(cid:5) which
`
`Juniper Ex. 1019-p. 3
`Juniper v Finjan
`
`
`
`shows an interface (cid:3)le for wrapping a few C (cid:3)le I(cid:14)O
`and memory management functions(cid:6)
`
`(cid:22)(cid:5) File (cid:23) file(cid:24)i (cid:5)(cid:22)
`(cid:21)module fileio
`(cid:21)(cid:9)
`(cid:18)include (cid:25)stdio(cid:24)h(cid:16)
`(cid:21)(cid:19)
`
`FILE (cid:5)fopen(cid:3)char (cid:5)filename(cid:4) char (cid:5)type(cid:8)(cid:10)
`int fclose(cid:3)FILE (cid:5)stream(cid:8)(cid:10)
`typedef unsigned int size(cid:2)t
`size(cid:2)t fread(cid:3)void (cid:5)ptr(cid:4) size(cid:2)t size(cid:4)
`size(cid:2)t nobj(cid:4) FILE (cid:5)stream(cid:8)(cid:10)
`size(cid:2)t fwrite(cid:3)void (cid:5)ptr(cid:4) size(cid:2)t size(cid:4)
`size(cid:2)t nobj(cid:4)FILE (cid:5)stream(cid:8)(cid:10)
`void (cid:5)malloc(cid:3)size(cid:2)t nbytes(cid:8)(cid:10)
`void free(cid:3)void (cid:5)(cid:8)(cid:10)
`
`The (cid:0)module directive sets the name of the initial(cid:4)
`ization function(cid:6) This is optional(cid:7) but is recom(cid:4)
`mended if building a Tcl (cid:6) module(cid:6) Everything
`inside the (cid:0)f(cid:2) (cid:0)g block is copied directly into the
`output(cid:7) allowing the inclusion of header (cid:3)les and ad(cid:4)
`ditional C code(cid:6) Afterwards(cid:7) C(cid:14)C(cid:15)(cid:15) function and
`variable declarations are listed in any order(cid:6) Build(cid:4)
`ing a new Tcl module is usually as easy as the fol(cid:4)
`lowing (cid:18)
`
`unix (cid:16) swig (cid:15)tcl file(cid:24)i
`unix (cid:16) gcc file(cid:2)wrap(cid:24)c (cid:15)I(cid:22)usr(cid:22)local(cid:22)include
`unix (cid:16) ld (cid:15)shared file(cid:2)wrap(cid:24)o (cid:15)o Fileio(cid:24)so
`
`(cid:3) A Tcl Example
`
`Newly added functions work like ordinary Tcl proce(cid:4)
`dures(cid:6) For example(cid:7) the following Tcl script copies
`a (cid:3)le using the binary (cid:3)le I(cid:14)O functions added in
`the previous example (cid:18)
`
`proc filecopy (cid:9)name name(cid:19) (cid:9)
`set buffer (cid:6)malloc (cid:7)(cid:10)
`set f (cid:6)fopen (cid:28)name r(cid:7)(cid:10)
`set f (cid:6)fopen (cid:28)name w(cid:7)(cid:10)
`set nbytes (cid:6)fread (cid:28)buffer (cid:28)f (cid:7)(cid:10)
`while (cid:9)(cid:28)nbytes (cid:16) (cid:19) (cid:9)
`fwrite (cid:28)buffer (cid:28)nbytes (cid:28)f(cid:10)
`set nbytes (cid:6)fread (cid:28)buffer (cid:28)f (cid:7)(cid:10)
`
`(cid:19) f
`
`close (cid:28)f (cid:10)
`fclose (cid:28)f(cid:10)
`free (cid:28)buffer
`
`(cid:19)
`
`signed and unsigned integers(cid:6) SWIG also allows de(cid:4)
`rived types such as pointers(cid:7) structures(cid:7) and classes(cid:7)
`but these are all encoded as pointers(cid:6)
`If an un(cid:4)
`known type is encountered(cid:7) SWIG assumes that it
`is a complex datatype that has been de(cid:3)ned ear(cid:4)
`lier(cid:6) No attempt is made to (cid:3)gure out what data
`that datatype actually contains or how it should
`be used(cid:6) Of course(cid:7) this this is only possible since
`SWIG(cid:11)s mapping of complex types into pointers al(cid:4)
`lows them to be handled in a uniform manner(cid:6) As
`a result(cid:7) SWIG does not normally need any sort of
`type(cid:4)mapping(cid:7) but typedef can be used to map any
`of the built(cid:4)in datatypes to new types if desired(cid:6)
`
`SWIG encodes pointers as hexadecimal strings with
`type(cid:4)information(cid:6) This type information is used to
`provide a run(cid:4)time type checking mechanism(cid:6) Thus(cid:7)
`a typical SWIG pointer looks something like the fol(cid:4)
`lowing (cid:18)
`
` e Vector p
`
`If this pointer is passed into a function requiring
`some other kind of pointer(cid:7) SWIG will generate a
`Tcl error and return an error message(cid:6) The NULL
`pointer is represented by the string (cid:17)NULL(cid:17)(cid:6) The
`SWIG run(cid:4)time type checker is saavy to typedefs
`and the relationship between base classes and de(cid:4)
`rived classes in C(cid:15)(cid:15)(cid:6) Thus if a user speci(cid:3)es
`
`typedef double Real(cid:8)
`
`the type checker knows that Real (cid:2) and double (cid:2)
`are equivalent (cid:2)more on C(cid:15)(cid:15) in a minute(cid:5)(cid:6) From
`the point of view of other Tcl extensions(cid:7) SWIG
`pointers should be seen as special (cid:17)handles(cid:17) except
`that they happen to contain the pointer value and
`its type(cid:6)
`
`To some(cid:7) this approach may seem horribly restric(cid:4)
`tive (cid:2)or error prone(cid:5)(cid:7) but keep in mind that SWIG
`was primarily designed to work with existing C ap(cid:4)
`plications(cid:6) Since most C programs pass complex
`datatypes around by reference this technique works
`remarkably well in practice(cid:6) Run time type(cid:4)checking
`also eliminates most common crashes by catching
`stupid mistakes such as using a wrong variable name
`or forgetting the (cid:17)(cid:25)(cid:17) character in a Tcl script(cid:6) While
`it is still possible to crash Tcl by forging a SWIG
`pointer value (cid:2)or making a call to buggy C code(cid:5)(cid:7)
`it is worth emphasizing that existing Tcl extensions
`may also crash if given an invalid handle(cid:6)
`
`(cid:3) Datatypes and Pointers
`
`(cid:3) Global Variables and Constants
`
`SWIG supports the basic datatypes of int(cid:7) short(cid:7)
`long(cid:7) float(cid:7) double(cid:7) char(cid:7) andvoid as well as
`
`SWIG can install global C variables and constants
`using Tcl(cid:11)s variable linkage mechanism(cid:6) Variables
`
`Juniper Ex. 1019-p. 4
`Juniper v Finjan
`
`
`
`may also be declared as (cid:16)read only(cid:17) within the Tcl
`interpreter(cid:6) The following example shows how vari(cid:4)
`ables and constants can be added to Tcl (cid:18)
`
`int Tree(cid:2)search(cid:3)Tree (cid:5)this(cid:4) char (cid:5)item(cid:8)(cid:10)
`int Tree(cid:2)remove(cid:3)Tree (cid:5)this(cid:4) char (cid:5)item(cid:8)(cid:10)
`void Tree(cid:2)print(cid:3)Tree (cid:5)t(cid:8)(cid:10)
`
`All C(cid:15)(cid:15) functions wrapped by SWIG explicitly re(cid:4)
`quire the this pointer as shown(cid:6) This approach has
`the advantage of working for all of the target lan(cid:4)
`guages(cid:6) It also makes it easier to pass objects be(cid:4)
`tween other C(cid:15)(cid:15) functions since every C(cid:15)(cid:15) object
`is simply represented as a SWIG pointer(cid:6) SWIG
`does not support function overloading(cid:7) but over(cid:4)
`loaded functions can be resolved by renaming them
`with the SWIG (cid:0)name directive as follows(cid:18)
`
`class List (cid:9)
`public(cid:23)
`
`List(cid:3)(cid:8)(cid:10)
`(cid:21)name(cid:3)ListMax(cid:8) List(cid:3)int maxsize(cid:8)(cid:10)
`(cid:24)(cid:24)(cid:24)
`
`(cid:19) T
`
`he approach used by SWIG is quite di(cid:23)erent than
`that used in systems such as Object Tcl or vtk
`(cid:8)vtk(cid:7) Wetherall(cid:9)(cid:6) As a result(cid:7) users of those systems
`may (cid:3)nd it to be confusing(cid:6) However(cid:7) It is impor(cid:4)
`tant to note that the modular design of SWIG allows
`the user to completely rede(cid:3)ne the output behavior
`of the system(cid:6) Thus(cid:7) while the current C(cid:15)(cid:15) imple(cid:4)
`mentation is quite di(cid:23)erent than other systems sup(cid:4)
`porting C(cid:15)(cid:15)(cid:7) it would be entirely possible write a
`new SWIG module that wrapped C(cid:15)(cid:15) classes into
`a representation similar to that used by Object Tcl
`(cid:2)in fact(cid:7) in might even be possible to use SWIG to
`produce the input (cid:3)les used for Object Tcl(cid:5)(cid:6)
`
`(cid:3) Multiple Files and Code Reuse
`
`An essential feature of SWIG is its support for mul(cid:4)
`tiple (cid:3)les and modules(cid:6) A SWIG interface (cid:3)le may
`include another interface (cid:3)le using the (cid:17)(cid:0)include(cid:17)
`directive(cid:6) Thus(cid:7) an interface for a large system
`might be broken up into a collection of smaller mod(cid:4)
`ules as shown
`
`(cid:0)module package
`(cid:0)(cid:9)
`(cid:10)include (cid:11)package(cid:12)h(cid:11)
`(cid:0)(cid:13)
`
`(cid:0)include geometry(cid:12)i
`(cid:0)include memory(cid:12)i
`(cid:0)include network(cid:12)i
`(cid:0)include graphics(cid:12)i
`(cid:0)include physics(cid:12)i
`
`(cid:0)include wish(cid:12)i
`
`(cid:22)(cid:22) SWIG file with variables and constants
`(cid:21)(cid:9)
`(cid:21)(cid:19)
`
`(cid:22)(cid:22) Some global variables
`extern int My(cid:2)variable(cid:10)
`extern char (cid:5)default(cid:2)path(cid:10)
`extern double My(cid:2)double(cid:10)
`
`(cid:22)(cid:22) Some constants
`(cid:18)define PI
` (cid:24)
`(cid:18)define PI(cid:2)
`PI(cid:22)(cid:24)
`enum colors (cid:9)red(cid:4)blue(cid:4)green(cid:19)(cid:10)
`const int SIZEOF(cid:2)VECTOR (cid:13) sizeof(cid:3)Vector(cid:8)(cid:10)
`
`(cid:22)(cid:22) A read only variable
`(cid:21)readonly
`extern int Status(cid:10)
`(cid:21)readwrite
`
`(cid:3) C(cid:9)(cid:9) Support
`
`The SWIG parser can handle simple C(cid:15)(cid:15) class
`de(cid:3)nitions and supports public inheritance(cid:7) virtual
`functions(cid:7) static functions(cid:7) constructors and de(cid:4)
`structors(cid:6) Currently(cid:7) C(cid:15)(cid:15) translation is performed
`by politely tranforming C(cid:15)(cid:15) code into C code and
`generating wrappers for the C functions(cid:6) For ex(cid:4)
`ample(cid:7) consider the following SWIG interface (cid:3)le
`containing a C(cid:15)(cid:15) class de(cid:3)nition(cid:18)
`
`(cid:0)module tree
`(cid:0)(cid:9)
`(cid:10)include (cid:11)tree(cid:12)h(cid:11)
`(cid:0)(cid:13)
`
`class Tree (cid:9)
`public(cid:14)
`Tree(cid:15)(cid:16)(cid:8)
`(cid:17)Tree(cid:15)(cid:16)(cid:8)
`void insert(cid:15)char (cid:18)item(cid:16)(cid:8)
`int
`search(cid:15)char (cid:18)item(cid:16)(cid:8)
`int
`remove(cid:15)char (cid:18)item(cid:16)(cid:8)
`static void print(cid:15)Tree (cid:18)t(cid:16)(cid:8)
`(cid:13)(cid:8)
`
`When translated(cid:7) the class will be access used the
`following set of functions (cid:2)created automatically by
`SWIG(cid:5)(cid:6)
`
`Tree (cid:5)new(cid:2)Tree(cid:3)(cid:8)(cid:10)
`void delete(cid:2)Tree(cid:3)Tree (cid:5)this(cid:8)(cid:10)
`void Tree(cid:2)insert(cid:3)Tree (cid:5)this(cid:4) char (cid:5)item(cid:8)(cid:10)
`
`Juniper Ex. 1019-p. 5
`Juniper v Finjan
`
`
`
`int main(cid:3)int(cid:4) char (cid:5)argv(cid:6)(cid:7)(cid:8)(cid:10)
`void create(cid:2)function(cid:3)char (cid:5)(cid:4)char (cid:5)(cid:4)DataType(cid:5)(cid:4)
`ParmList (cid:5)(cid:8)(cid:10)
`void link(cid:2)variable(cid:3)char (cid:5)(cid:4)char (cid:5)(cid:4)DataType (cid:5)(cid:8)(cid:10)
`void declare(cid:2)const(cid:3)char (cid:5)(cid:4)int(cid:4)char (cid:5)(cid:8)(cid:10)
`void initialize(cid:3)void(cid:8)(cid:10)
`void headers(cid:3)void(cid:8)(cid:10)
`void close(cid:3)void(cid:8)(cid:10)
`void usage(cid:2)var(cid:3)char (cid:5)(cid:4)DataType(cid:5)(cid:4)char (cid:5)(cid:5)(cid:8)(cid:10)
`void usage(cid:2)func(cid:3)char (cid:5)(cid:4)DataType(cid:5)(cid:4)ParmList(cid:5)(cid:4)
`char (cid:5)(cid:5)(cid:8)(cid:10)
`void usage(cid:2)const(cid:3)char (cid:5)(cid:4)int(cid:4)char(cid:5)(cid:4)char(cid:5)(cid:5)(cid:8)(cid:10)
`void set(cid:2)module(cid:3)char (cid:5)(cid:8)(cid:10)
`void set(cid:2)init(cid:3)char (cid:5)(cid:8)(cid:10)
`(cid:19)(cid:10)
`
`Descriptions of these functions can be found in the
`SWIG users manual(cid:6) To build a new version of
`SWIG(cid:7) the user only needs to provide the function
`de(cid:3)nitions and a main program which looks some(cid:4)
`thing like the following (cid:18)
`
`(cid:22)(cid:22) SWIG main program
`
`(cid:18)include (cid:17)swig(cid:24)h(cid:17)
`(cid:18)include (cid:17)swigtcl(cid:24)h(cid:17)
`
`int main(cid:3)int argc(cid:4) char (cid:5)(cid:5)argv(cid:8) (cid:9)
`
`Language (cid:5)lang(cid:10)
`
`lang (cid:13) new TCL(cid:10)
`SWIG(cid:2)main(cid:3)argc(cid:4)argv(cid:4)lang(cid:4)(cid:3)Documentation (cid:5)(cid:8) (cid:8)(cid:10)
`
`(cid:19) W
`
`hen linked with a library (cid:3)le(cid:7) any extensions
`and modi(cid:3)cations can now be used with the SWIG
`parser(cid:6) While writing a new language de(cid:3)nition is
`not entirely trivial(cid:7) it can usually be done by just
`copying one of the existing modules and modifying
`it appropriately(cid:6)
`
`
`
`Examples
`
`(cid:3) A C(cid:13)Tcl Linked List
`
`SWIG can be used to build simple data structures
`that are usuable in both C and Tcl(cid:6) The follow(cid:4)
`ing code shows a SWIG interface (cid:3)le for building a
`simple linked list(cid:6)
`
`(cid:22)(cid:5) File (cid:23) list(cid:24)i (cid:5)(cid:22)
`(cid:21)(cid:9)
`struct Node (cid:9)
`Node(cid:3)char (cid:5)n(cid:8) (cid:9)
`
`Common operations can be placed into a SWIG
`library for use in all applications(cid:6) For example(cid:7)
`the (cid:0)include wish(cid:12)i directive tells SWIG to in(cid:4)
`clude code for the Tcl AppInit(cid:15)(cid:16) function needed
`to rebuild the wish program(cid:6) The library can also
`be used to build modules allowing SWIG to be
`used with common Tcl extensions such as Expect
`(cid:8)Expect(cid:9)(cid:6) Of course(cid:7) the primary use of the library is
`with large applications such as Open(cid:4)Inventor which
`contain hundreds of modules and a substantial class
`hierarchy (cid:8)Invent(cid:9)(cid:6)
`In this case a user could use
`SWIG(cid:11)s include mechanism to selectively pick which
`modules they wanted to use for a particular prob(cid:4)
`lem(cid:6)
`
`(cid:3) The Documentation System
`
`SWIG produces documentation in ASCII(cid:7) LaTeX(cid:7)
`or HTML format describing everything that was
`wrapped(cid:6) The documentation follows the syntax
`rules of the target language and can can be further
`enhanced by adding descriptions in a C(cid:14)C(cid:15)(cid:15) com(cid:4)
`ment immediately following a declaration(cid:6) These
`comments may also contain embedded LaTeX or
`HTML commands(cid:6) For example(cid:18)
`
`extern size(cid:2)t fread(cid:3)void (cid:5)ptr(cid:4) size(cid:2)t size(cid:4)
`size(cid:2)t nobj(cid:4) FILE (cid:5)stream(cid:8)(cid:10)
`(cid:22)(cid:5) (cid:9)!tt fread(cid:19) reads from (cid:9)!tt stream(cid:19) into
`the array (cid:9)!tt ptr(cid:19) at most (cid:9)!tt nobj(cid:19) objects
`of size (cid:9)!tt size(cid:19)(cid:24)
`(cid:9)!tt fread(cid:19) returns
`the number of objects read(cid:24) (cid:5)(cid:22)
`
`When output by SWIG and processed by LaTeX(cid:7)
`this appears as follows (cid:18)
`
`size t (cid:14) fread ptr size nobj stream
`
`fread reads from stream into the array ptr at
`most nobj objects of size size(cid:6) fread returns
`the number of objects read(cid:6)
`
`(cid:3) Extending the SWIG System
`
`Finally(cid:7) SWIG itself can be extended by the user to
`provide new functionality(cid:6) This is done by modi(cid:4)
`fying an existing or creating a new language class(cid:6)
`A typical class must specify the following functions
`that determine the behavior of the parser output (cid:18)
`
`(cid:22)(cid:22) File (cid:23) swigtcl(cid:24)h
`class TCL (cid:23) public Language (cid:9)
`private(cid:23)
`(cid:22)(cid:22) Put private stuff here
`public (cid:23)
`TCL(cid:3)(cid:8)(cid:10)
`
`Juniper Ex. 1019-p. 6
`Juniper v Finjan
`
`
`
`Aside from the pointer values(cid:7) our script acts like
`any other Tcl script(cid:6) However(cid:7) we have built up a
`real C data structure that could be easily passed to
`other C functions if needed(cid:6)
`
`(cid:3) Using C Data(cid:13)Structures with Tk
`
`In manner similar to the linked list example(cid:7) Tcl(cid:14)Tk
`can be used to build complex C(cid:14)C(cid:15)(cid:15) data struc(cid:4)
`tures(cid:6) For example(cid:7) suppose we wanted to inter(cid:4)
`actively build a graph of (cid:16)Nodes(cid:17) for use in a C
`application(cid:6) A typical interface (cid:3)le might include
`the following functions(cid:18)
`
`(cid:21)(cid:9)
`(cid:18)include (cid:17)nodes(cid:24)h(cid:17)
`(cid:21)(cid:19)
`
`(cid:21)include wish
`extern Node (cid:5)new(cid:2)node(cid:3)(cid:8)(cid:10)
`extern void AddEdge(cid:3)Node (cid:5)n (cid:4) Node (cid:5)n(cid:8)(cid:10)
`
`Within a Tcl(cid:14)Tk script(cid:7) loosely based on one to
`make ball and stick graphs in (cid:8)Ousterhout(cid:9)(cid:7) a graph
`could be built as follows(cid:18)
`
`proc makeNode (cid:9)x y(cid:19) (cid:9)
`global nodeX nodeY nodeP edgeFirst edgeSecond
`set new (cid:6)(cid:24)create oval (cid:6)expr (cid:28)x(cid:15) (cid:7) !
`(cid:6)expr (cid:28)y(cid:15) (cid:7) (cid:6)expr (cid:28)x" (cid:7) !
`(cid:6)expr (cid:28)y" (cid:7) (cid:15)outline black !
`(cid:15)fill white (cid:15)tags node(cid:7)
`set newnode (cid:6)new(cid:2)node(cid:7)
`set nodeX(cid:3)(cid:28)new(cid:8) (cid:28)x
`set nodeY(cid:3)(cid:28)new(cid:8) (cid:28)y
`set nodeP(cid:3)(cid:28)new(cid:8) (cid:28)newnode
`set edgeFirst(cid:3)(cid:28)new(cid:8) (cid:9)(cid:19)
`set edgeSecond(cid:3)(cid:28)new(cid:8) (cid:9)(cid:19)
`
`(cid:19) p
`
`roc makeEdge (cid:9)first second(cid:19) (cid:9)
`global nodeX nodeY nodeP edgeFirst edgeSecond
`set x (cid:28)nodeX(cid:3)(cid:28)first(cid:8)(cid:10) set y (cid:28)nodeY(cid:3)(cid:28)first(cid:8)
`set x (cid:28)nodeX(cid:3)(cid:28)second(cid:8)(cid:10) set y (cid:28)nodeY(cid:3)(cid:28)second(cid:8)
`set edge (cid:6)(cid:24)c create line (cid:28)x (cid:28)y (cid:28)x (cid:28)y !
`(cid:15)tags edge(cid:19)
`(cid:24)c lower edge
`lappend edgeFirst(cid:3)(cid:28)first(cid:8) (cid:28)edge
`lappend edgeSecond(cid:3)(cid:28)first(cid:8) (cid:28)edge
`AddEdge (cid:28)nodeP(cid:3)(cid:28)first(cid:8) (cid:28)nodeP(cid:3)(cid:28)second(cid:8)
`
`(cid:19) T
`
`hese functions create Tk canvas items(cid:7) but also
`attach a pointer to a C data structure to each
`one(cid:6) This is done by maintaining an associative ar(cid:4)
`ray mapping item identi(cid:3)ers to pointers (cid:2)with the
`nodeP(cid:15)(cid:16) array(cid:5)(cid:6) When a particular (cid:16)node(cid:17) is refer(cid:4)
`enced later(cid:7) we can use this to get its pointer use it
`in calls to C functions(cid:6)
`
`name (cid:13) new char(cid:6)strlen(cid:3)n(cid:8)" (cid:7)(cid:10)
`strcpy(cid:3)name(cid:4)n(cid:8)(cid:10)
`next (cid:13) (cid:10)
`(cid:19)(cid:10)
`char (cid:5)name(cid:10)
`Node (cid:5)next(cid:10)
`(cid:19)(cid:10)
`(cid:21)(cid:19)
`
`(cid:22)(cid:22) Just add struct definition to
`(cid:22)(cid:22) the interface file(cid:24)
`
`struct Node (cid:9)
`Node(cid:3)char (cid:5)(cid:8)(cid:10)
`char (cid:5)name(cid:10)
`Node (cid:5)next(cid:10)
`(cid:19)(cid:10)
`
`When used in a Tcl script(cid:7) we can now create new
`nodes and access individual members of the Node
`structure(cid:6)
`In fact(cid:7) we can write code to convert
`between Tcl lists and linked lists entirely in Tcl as
`shown (cid:18)
`
`(cid:18) Builds linked list from a Tcl list
`proc buildlist (cid:9)list head(cid:19) (cid:9)
`set nitems (cid:6)llength (cid:28)list(cid:7)(cid:10)
`for (cid:9)set i (cid:19) (cid:9)(cid:28)i (cid:25) (cid:28)nitems(cid:19) (cid:9)incr i (cid:15) (cid:19) (cid:9)
`set item (cid:6)lrange (cid:28)list (cid:28)i (cid:28)i(cid:7)
`set n (cid:6)new(cid:2)Node (cid:28)item(cid:7)
`Node(cid:2)set(cid:2)next (cid:28)n (cid:28)head
`set head (cid:28)n
`
`(cid:19) r
`
`eturn (cid:28)head
`
`(cid:19) (cid:18)
`
`Builds a Tcl list from a linked list
`proc get(cid:2)list (cid:9)llist(cid:19) (cid:9)
`set list (cid:9)(cid:19)
`while (cid:9)(cid:28)llist (cid:12)(cid:13) (cid:17)NULL(cid:17)(cid:19) (cid:9)
`lappend list (cid:6)Node(cid:2)name(cid:2)get (cid:28)llist(cid:7)
`set llist (cid:6)Node(cid:2)get(cid:2)next (cid:28)llist(cid:7)
`
`(cid:19) r
`
`eturn (cid:28)list
`
`(cid:19) W
`
`hen run interactively(cid:7) we could now use our Tcl
`functions as follows(cid:6)
`
`(cid:21) set l (cid:9)John Anne Mary Jim(cid:19)
`John Anne Mary Jim
`(cid:21) set ll (cid:6)buildlist (cid:28)l (cid:2) (cid:2)Node(cid:2)p(cid:7)
`(cid:2) cab(cid:2)Node(cid:2)p
`(cid:21) get(cid:2)list (cid:28)ll
`Jim Mary Anne John
`(cid:21) set ll (cid:6)buildlist (cid:9)Mike Peter Dave(cid:19) (cid:28)ll(cid:7)
`(cid:2) cc (cid:2)Node(cid:2)p
`(cid:21) get(cid:2)list (cid:28)ll
`Dave Peter Mike Jim Mary Anne John
`(cid:21)
`
`Juniper Ex. 1019-p. 7
`Juniper v Finjan
`
`
`
`(cid:3) Parsing a C(cid:9)(cid:9) Simple Class Hier(cid:13)
`archy
`
`(cid:21) Shape(cid:2)set(cid:2)position (cid:28)c (cid:15)
`(cid:21) Circle(cid:2)print(cid:2)position (cid:28)c
`xc (cid:13) (cid:15)(cid:4) yc (cid:13)
`
`(cid:21) I
`
`n our example(cid:7) we have created new Circle
`and Square objects(cid:7) but these can be used inter(cid:4)
`changably in any functions de(cid:3)ned in the Shape
`base class(cid:6) The SWIG type checker is encoded with
`the class hierarchy and knows the relationship be(cid:4)
`tween the di(cid:23)erent classes(cid:6) Thus(cid:7) while an object
`of type Circle is perfectly acceptable to a func(cid:4)
`tion operating on shapes(cid:7)
`it would be unaccept(cid:4)
`able to a function operating only on the Square
`type(cid:6) As in C(cid:15)(cid:15)(cid:7) any functions in the base class
`can be called in the derived class as shown by the
`Circle print position function above(cid:6)
`
` Using SWIG in Real Applications
`
`So far only a few simple toy examples have been pre(cid:4)
`sented to illustrate the operation of SWIG in gen(cid:4)
`eral(cid:6) This section will describe how SWIG can be
`used with larger applications(cid:6)
`
`(cid:3) Use in Scienti(cid:14)c Applications
`
`Many users(cid:7) especially within the scienti(cid:3)c and en(cid:4)
`gineering community(cid:7) have spent years developing
`simulation codes(cid:6) While many of these users appre(cid:4)
`ciate the power that a scripting language can pro(cid:4)
`vide(cid:7) they don(cid:11)t want to completely rewrite their ap(cid:4)
`plications or spend all of their time trying to build a
`user(cid:4)interface (cid:2)most users would rather be working
`on the scienti(cid:3)c problem at hand(cid:5)(cid:6) While SWIG
`certainly won(cid:11)t do everything(cid:7) it can dramatically
`simplify this process(cid:6)
`
`As an example(cid:7) the (cid:3)rst SWIG application was the
`SPaSM molecular dynamics code developed at Los
`Alamos National Laboratory (cid:8)Beazley(cid:7) Lomdahl(cid:9)(cid:6)
`This code is currently being used for materials sci(cid:4)
`ence problems and consists of more than C func(cid:4)
`tions and about lines of code(cid:6) In order to use
`SWIG(cid:7) only the main(cid:15)(cid:16) function had to be rewrit(cid:4)
`ten along with a few other minor modi(cid:3)cations(cid:6) The
`full user interface is built using a collection of mod(cid:4)
`ules for simulation(cid:7) graphics(cid:7) memory management(cid:7)
`etc(cid:6)(cid:6)(cid:6) A user may also supply their own interface
`modules(cid:22)allowing the code to be easily extended
`with new functionality capabilities as needed(cid:6) All of
`the interface (cid:3)les(cid:7) containing a few hundred lines of
`function declarations(cid:7) are automatically translated
`
`As mentioned earlier(cid:7) SWIG can handle C(cid:15)(cid:15)
`classes and public inheritance(cid:6) The following exam(cid:4)
`ple provides a few classes and illustrates how this
`is accomplished (cid:2)some code has been ommitted for
`readability(cid:5)(cid:6)
`
`(cid:22)(cid:22) A SWIG inheritance example
`(cid:21)module shapes
`(cid:21)(cid:9)
`(cid:18)include (cid:17)shapes(cid:24)h(cid:17)
`(cid:21)(cid:19)
`
`class Shape (cid:9)
`private(cid:23)
`double xc(cid:4) yc(cid:10)
`public(cid:23)
`virtual double area(cid:3)(cid:8) (cid:13) (cid:10)
`virtual double perimeter(cid:3)(cid:8) (cid:13) (cid:10)
`void
`set(cid:2)position(cid:3)double x(cid:4) double y(cid:8)(cid:10)
`void
`print(cid:2)posit