Path: news.ruhr-uni-bochum.de!news.rwth-aachen.de!uni-paderborn.de!fu-berlin.de!main.Germany.EU.net!Frankfurt.Germany.EU.net!howland.erols.net!newsfeed.internetmci.com!news.mathworks.com!usenet.eel.ufl.edu!psgrain!nntp.teleport.com!usenet From: beazley@elmo.cs.utah.edu (David Beazley) Newsgroups: comp.lang.perl.announce,comp.lang.perl.misc Subject: ANNOUNCE : SWIG 1.0 (Final) for Perl Followup-To: comp.lang.perl.misc Date: 3 Sep 1996 14:33:18 GMT Organization: University of Utah Computer Science Department Lines: 570 Approved: merlyn@stonehenge.com (comp.lang.perl.announce) Message-ID: <50hfje$oij@nadine.teleport.com> NNTP-Posting-Host: kelly.teleport.com X-Disclaimer: The "Approved" header verifies header information for article transmission and does not imply approval of content. Xref: news.ruhr-uni-bochum.de comp.lang.perl.announce:415 comp.lang.perl.misc:43940 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"; 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 %} 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 'Majordomo@cs.utah.edu' 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 beazley@cs.utah.edu http://www.cs.utah.edu/~beazley ---------------------------------------------------------------------