Subject: ANNOUNCE : SWIG 1.0 (Final) for Perl
From: [email-masked] (David Beazley)
Date: 3 Sep 1996 14:33:18 GMT
Newsgroups: comp.lang.perl.announce,comp.lang.perl.misc

Announcing SWIG 1.0 for Perl

September 2, 1996

I'm pleased to announce the release of SWIG 1.0 (Final).  After many months 
of beta testing, suggestions for improvements, and enhancements, this is 
the first "official" release.   It is available via anonymous FTP at

    ftp://ftp.cs.utah.edu/pub/beazley/SWIG

More information is also available on the SWIG homepage at
    
    http://www.cs.utah.edu/~beazley/SWIG
    
1.   What is SWIG? (Executive Summary)
---------------------------------------

SWIG (Simplified Wrapper and Interface Generator), is a compiler that turns 
ANSI C/C++ declarations into the bindings needed to access C or C++ from 
common scripting languages including Perl, Tcl, and Python.  This makes it 
easy to develop interactive and extensible C/C++ applications.  SWIG 
requires no modifications to your C code, and is independent of the target 
language--thus why spend time trying to find the "best" scripting language, 
when you can use all of them?  SWIG is primarily used for controlling, 
debugging, testing, and rapid prototyping of C/C++ applications.

2.  A Simple SWIG Example
-------------------------

Suppose you were really into computing factorials and you wanted to add the 
factorial function to Perl5.  Here's a C function :

    /* fact.c */
    
    int fact(int n) {
        if (n <= 1) return 1;
        else return n*fact(n-1);
    }
    
Now, here's a SWIG interface specification file for it:

    // fact.i : SWIG Interface file 
    %module fact 
    %{
    /* Put header files here (if needed)
    %}

    extern int fact(int n);

Let's turn this into a Perl5 dynamically loadable module ....
    
    unix> swig -perl5 fact.i
    Making wrappers for Perl5
    unix> gcc -c fact.c fact_wrap.c \
          -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
    unix> ld -shared fact.o fact_wrap.o -o fact.so
    unix> perl5
    use fact;
    print fact::fact(4),"\n";
    <ctrl-d>
    24

When invoked, SWIG creates the file 'fact_wrap.c'.  This file should be 
compiled and linked with the C file to create a module.  SWIG also creates 
a file 'fact.pm' needed to load the module into Perl5.
    
Now let's turn this into a Python module:

    unix> swig -python fact.i
    Making wrappers for Python
    unix> gcc -c fact.c fact_wrap.c -I/usr/local/include/Py 
    unix> ld -shared fact.o fact_wrap.o -o factmodule.so
    unix> python
    Python 1.3 (Mar 26 1996)    [GCC 2.7.0]
    Copyright 1991-1995 Stichting Mathematisch Centrum
    Amsterdam
    >>> import fact
    >>> print fact.fact(4)
    24
    
Finally, we can create a Tcl module :

    unix> swig -tcl fact.i
    Making wrappers for Tcl.
    unix> gcc -c fact.c fact_wrap.c -I/usr/local/include
    unix> ld -shared fact.o fact_wrap.o -o fact.so
    unix> tclsh7.5
    % load ./fact.so fact
    % fact 4
    24
    %

So, in a manner of minutes, we've added the factorial function to Tcl, 
Python, and Perl5.  I think you get the idea...

3.  SWIG Applications
---------------------

SWIG was designed for a number of applications.   This is how I use it :

Controlling C/C++ programs :

More often than not, writing a decent interface to a C/C++ program is a 
pain in the butt!  With SWIG, you can throw away your main program, and use 
a scripting language instead.  This, in turn, let's you do almost anything 
else.  You can write scripts to control the application, interactively type 
commands, or write a GUI using Tk.  At Los Alamos National Laboratory, SWIG 
is used to automatically build scripted interfaces to simulations running 
on the 1024 processor Connection Machine 5 supercomputer.  It works!

Debugging and testing :

SWIG requires no modifications to C/C++ code, so why not use Perl as a 
C/C++ debugger?  You can create new objects, call individual C functions, 
query the value of C variables, and write test scripts--all in Perl!  When 
you're done, blow away the SWIG interface file (well, maybe you want to 
save it), and you're left with normal looking C code that can be used in 
applications that might not even involve Perl (although why would want to 
do that?).  Personally, I think SWIG excels at this.

Rapid Prototyping :

With SWIG, you can use Perl to rapidly prototype C/C++ code.  New ideas can 
be first tested with a Perl script and then reimplemented in C if necessary.  
Since SWIG uses ANSI C/C++ syntax, modules can usually be made out of 
existing code relatively quickly (often in only a matter of minutes).

Processing Weird Files and Input Formats :

Perl's text/file processing capabilities make it an ideal interface to a 
variety of tools---particularly in science and engineering where most users 
are already familar with awk and/or Perl.  It's amazing how much time one 
can waste just trying to transfer data between different packages.  By 
building a Perl interface to your C program, you get all of Perl's powerful 
text processing features for free and you end up with a C program that can 
easily handle almost any input and output format.  I think this is cool.

Building Tools and Modules :

SWIG can be used to build general purpose modules and tools.  While this 
wasn't my original motivation, it is certainly possible to take a package 
and turn it into a general purpose Perl5, Tcl, or Python module.  However, 
most scripting languages already have high quality modules to do almost 
anything you would ever want to do.  I would recommend checking the FTP 
archives and newsgroups to see if a module already exists before wrapping 
it with SWIG.  Personally, I feel that SWIG is better suited towards 
applications programming, not generic module building.  However, in defense of 
SWIG, sometimes an existing module may be missing functionality or operate 
poorly.  With SWIG, you can often correct this by building your own module.

Impressing Your Friends :

Pick a big library, wrap it with SWIG, make a Tk interface, take a month of 
vacation, then show it to your boss/advisor.  Obviously, he/she will think 
you've been working extremely hard and that you probably need a break...  
(I haven't actually tested this theory, but it could happen).
    
4.   SWIG Features
-------------------

SWIG has been designed to work with most types of C code and a moderate
subset of C++.  Here's a summary of SWIG's features :

C/C++ support :

    *   Uses ANSI C/C++ syntax (if you've written a header file, then
        you know how to use SWIG).
        
    *   Supports almost all C basic datatypes.
        (int, short, char, long, float, double, void)
        
    *   Provides type-checked C/C++ pointers.
    
    *   Supports complex datatypes as pointers (structs, classes, unions) 
    
    *   Can create wrapper functions, global variables, and constants.
    
    *   Simple C++ class parsing
            *   Constructors
            *   Destructors
            *   Member functions and attributes
            *   Virtual functions
            *   Static functions.
            *   Public inheritance (single inheritance only).
            *   C++ references

    *   Requires no modifications to C/C++ code (works with ordinary C
        functions).
        
    *   Follows C typedef declarations.

Target languages :

    *   Perl5 (5.002 or later)
    
    *   Perl4

    *   Tcl 
    
    *   Python 
    
    *   Guile-iii
    
Other SWIG features :

    *   Supports multiple files and modules
    
    *   Automatically generates documentation (ASCII, HTML, LaTeX)
    
    *   Extensible with new language modules
    
    *   Fully documented
    
    *   Installation via a GNU autoconf configure script.
    
    *   Includes a directory of examples.
    
Perl specific features :
    
    *   Can rebuild both Perl4 and Perl5 executables (However, C++ only
        works with Perl5).
        
    *   Supports dynamically loadable modules for Perl5.
    
    *   SWIG type-checked pointers are compatible with those generated
        by xsubpp.

5.  A Slightly More Complex SWIG Example
----------------------------------------

Suppose, for some really strange reason, you wanted to add some functions 
from the C stdio I/O library to do binary I/O in Perl5.  A SWIG interface 
file might look like this:

    // File : binio.i
    %module binio
    %{
    #include <stdio.h>
    %}
    
    FILE      *fopen(char *filename, char *type);
    int        fclose(FILE *stream);
    
    typedef unsigned int size_t;
    
    size_t     fread(void *ptr, size_t size, size_t nobj, FILE *stream);
    size_t     fwrite(void *ptr, size_t size, size_t nobj, FILE *stream);
    
    // Now put some memory management functions
    void       *malloc(size_t nbytes);
    void        free(void *);
    
To build a Perl5 module, do this :

    unix> swig -perl5 binio.i
    unix> gcc -c binio_wrap.c -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
    unix> ld -G binio_wrap.o -o binio.so
          
Now, we can use our module as follows:

    use binio;
    sub filecopy {
        local($name1,$name2) = @_;
        $buffer = &binio::malloc(8192);
        $f1 = &binio::fopen($name1,"r");
        $f2 = &binio::fopen($name2,"w");
        $nbytes = &binio::fread($buffer,1,8192,$f1);
        while ($nbytes > 0) {
            &binio::fwrite($buffer,1,8192,$f2);
            $nbytes = &binio::fread($buffer,1,8192,$f1);
        }
        &binio::fclose($f1);
        &binio::fclose($f2);
        &binio::free($buffer);
    }

While only a toy example, this illustrates a number of key features about 
SWIG.  First, we used FILE * and void * pointers freely in a manner 
entirely similar to C.  Secondly, SWIG does not require additional 
specifications (ie.  a typemap) to handle complex datatypes (which are 
always represented by pointers).

To avoid accidently shooting yourself in the foot, SWIG pointers are fully 
type-checked.  If the following commands appeared

    $buffer = &binio::malloc(8192);
    &binio::fclose($buffer);

you would get the following Perl error :

    Type error in argument 1 of fclose. Expected FilePtr. at xxxx line 2.

SWIG's type checking mechanism catches most common types of programming 
errors.  Of course if your C code is buggy, that's another story....

6.  A C++ example
-----------------

To illustrate SWIG's handling of C++, here's a simple interface file
with a few classes :

   // shapes.i
   // SWIG interface file for shapes class
   %module shapes
   %{
   #include "shapes.h"
   %}

   class Shape {
   public:
       virtual double area() = 0;
       virtual double perimeter() = 0;
       void    set_location(double x, double y);
   };
   class Circle : public Shape {
   public:
       Circle(double radius);
      ~Circle();
       double area();
       double perimeter();
   };
   class Square : public Shape {
   public:
       Square(double size);
      ~Square();
       double area();
       double perimeter();
   }

When translated, SWIG will create the following set of low-level accessor 
functions that require an extra argument containing the "this" pointer to 
the object :

    double  Shape_area(Shape *s);
    double  Shape_perimeter(Shape *s);
    void    Shape_set_location(Shape *s, double x, double y)
    
    Circle *new_Circle(double radius);
    void    delete_Circle(Circle *c);
    double  Circle_area(Circle *c);
    double  Circle_perimeter(Circle *c);
    void    Circle_set_location(Circle *c, double x, double y);

    Square *new_Square(double width);
    void    delete_Square(Square *s);
    double  Square_area(Square *s);
    double  Square_perimeter(Square *s);
    void    Square_set_location(Square *s, double x, double y);
    
Within a Perl5 script, the C++ class can be accessed as follows:

    use shapes;
    $c = shapes::new_Circle(7);
    $s = shapes::new_Square(10);
    print shapes::Circle_area($c),"\n";
    # Now use the base class
    print shapes::Shape_area($c),"\n";
    print shapes::Shape_area($s),"\n";
    shapes::Shape_set_location($s,2,-3);
    print shapes::Shape_perimeter($s);
    # Now try to put a Square peg in a circular hole
    $a = shapes::Circle_area($s);

When run, you'll get the following :

    153.93804
    153.93804
    100.00000
    40.00000
    Type error in argument 1 of Circle_area. Expected CirclePtr. 

SWIG provides access to C++ objects and C data structures, but is not an 
object oriented extension to Perl5.  

7.  Multiple Files and Modules
-------------------------------

SWIG allows you to assemble collections of modules and input files.  For 
example, you could build an entire package using the following file

    // file : package.i
    %module package
    %{
    %}
    
    %include perlmain.i
    %include matlab.i
    %include physics.i
    %include network.i
    %include analysis.i
    %include initcond.c

SWIG will go off and wrap everything in the files you give it.  Files may 
be language specific or language independent.  For example, the file 
'perlmain.i' above contains the code needed to rebuild a static version of 
Perl5, but would not be included when building a Python module.  SWIG can 
also process C source and header files if they are sufficiently clean and 
use ANSI C syntax.  The '%include initcond.c' directive above would simply 
load the C source file, and try to wrap all of the functions and global 
variables in it (This process isn't foolproof, but it beats a kick to the 
head).

In a large system, you could make SWIG part of the makefile and have it 
invoked automatically.  It's also easy to extend an existing system, by 
simply writing a new interface file such as :

    // file : mypackage.i
    %module package
    %{
    %}
    
    %include package.i                // Include all of the old stuff
    %include opengl.i                 // Add OpenGL 
    // Now add more functions here 
    ...

This would include all of the modules in the 'package.i' file above, all of 
the functions in 'opengl.i' plus any new functions in this file.  Given a 
set of existing modules, it's relatively easy to create a new system with 
SWIG.
    
8. SWIG and XS/xsubpp
----------------------

Given the xsubpp tool provided with Perl5, why would anyone want to 
consider using SWIG?  In reality, I feel that the tools serve different 
purposes.  SWIG is primarily designed to easily build Perl interfaces to 
C/C++ applications (often special purpose), while xsubpp is better suited 
for general purpose Perl5 module building.  Here are some differences 
between the two systems :

SWIG features (not found in xsubpp) :

    *   Uses ANSI C/C++ syntax and is insensitive to formatting.
    *   Does not require a typemap.
    *   Provides a richer pointer handling mechanism (that follows
        C typedef statements and C++ class hierarchies).
    *   Full support for C global variables and constants.
    *   Automatic documentation generation
    *   Multiple file support
    *   Multiple target languages
    
xsubpp features (not found in SWIG) :

    *   Better support for datatype handling, via typemaps.
    *   Somewhat better integration with Perl5 (since almost all Perl5 
        modules use it).
    *   Provides a mechanism for special purpose processing
        in wrapper functions.
    *   Default/optional function arguments.
    *   Support for returning parameters in a function argument.

As for compatibility between the two systems, SWIG scalar values (doubles, 
ints, strings) are fully compatible with anything created with xsubpp.  C 
pointers are also compatible between the two systems provided they are 
mapped to the T_PTROBJ type in the xsubpp typemap (as this is the type SWIG 
uses).

Eventually, it may be possible to use SWIG to produce input files 
for xsubpp, but this is not currently supported (due to the limit
of only 24 hours in a day).

9.  Limitations of SWIG
------------------------

While SWIG handles a wide variety of C/C++ code, SWIG does not currently 
support the following :

    *   Variable length arguments
    
    *   Arrays and function pointers (partially supported)
    
    *   Default/optional arguments
    
    *   Templates, operator overloading, multiple inheritance

Finally, I developed SWIG to be a practical problem solving tool for myself 
and others who write code--particularly scientists, engineers, and 
programmers.  I continually make improvements and clean up the current 
implementation.  However, I have never considered SWIG to be an academic 
exercise in language unification or programming environments---nor do I 
consider it to be a software engineering tool appropriate for developing 
big commercial packages.  SWIG represents a balance of simplicity and 
functionality.  Most users find it to be extremely easy to use and 
surprisingly powerful.  Besides, I'm not aware of too many other tools 
capable of wrapping the entire OpenGL library into 5 different scripting 
languages in less than 20 minutes?  I rest my case...

10. System requirements and compatibility
-----------------------------------------

SWIG supports Perl 5.002 or newer versions.    Earlier versions
of Perl5 may or may not work with the current SWIG implementation.
SWIG also includes support for Perl4.036, but you should really
consider upgrading to Perl5...

To compile and use SWIG with Perl5, you will need :
    
    *   A C++ compiler  (ie. g++)
    *   An ANSI C compiler
    *   yacc or bison.
    *   Perl (you knew this)
    
SWIG is easily installed using a GNU autoconf script I have tested the 
installation on the following systems :
    
    *   SunOs 4.1.3
    *   Solaris 2.5.1
    *   Irix 5.3
    *   Irix 6.2
    *   AIX 4.1
    *   HPUX
    *   Linux
    *   MkLinux
    *   UNICOS 
    *   Power MachTen 4.0.2

Most of the provided examples have been tested under Solaris 2.5.1, Irix 
5.3, and MkLinux so you may need to do a little tweaking to get the 
provided examples to compile on other machines (especially if you're using 
dynamic loading).

11.  Availability and Resources
--------------------------------

SWIG is available via anonymous FTP at :
    
        ftp://ftp.cs.utah.edu/pub/beazley/SWIG
        
The SWIG homepage contains up-to-date information and online documentation :
    
        http://www.cs.utah.edu/~beazley/SWIG
        
You can subscribe to the SWIG mailing list by sending a message to 
[email-masked]' with the following body :
    
        subscribe swig

SWIG is extensively documented and comes with a 120 page user manual 
describing everything from how to use SWIG to how to write your own 
scripting language module.  I hate black boxes so I've tried to make the 
documentation as complete as possible.

12.  SWIG is FREE
-----------------

SWIG is free software.  You can do anything you want with it (including 
distribution), provided that you retain its original copyright notices, 
don't claim that you wrote it, and don't sue people if it breaks (SWIG 
comes "as is").

Further questions can be sent to the e-mail address below.   

Cheers,

Dave Beazley
---------------------------------------------------------------------
Dave Beazley
Department of Computer Science
University of Utah
Salt Lake City, Utah   84112
[email-masked]                   http://www.cs.utah.edu/~beazley
---------------------------------------------------------------------