
The SWIG documentation is being updated to reflect new SWIG features and enhancements. However, this update process is not quite finished--there is a lot of old SWIG-1.1 documentation and it is taking some time to update all of it. Please pardon our dust (or volunteer to help!).
This documentation has not been completely updated from SWIG-1.1, but most of the topics still apply to the current release. Make sure you read the SWIG Basics chapter before reading any of these chapters. Also, SWIG-1.3.10 features extensive changes to the implementation of typemaps. Make sure you read the Typemaps chapter above if you are using this feature.
SWIG (Simplified Wrapper and Interface Generator) is a software development tool for building scripting language interfaces to C and C++ programs. Originally developed in 1995, SWIG was first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for building user interfaces to simulation codes running on the Connection Machine 5 supercomputer. In this environment, scientists needed to work with huge amounts of simulation data, complex hardware, and a constantly changing code base. The use of a scripting language interface provided a simple yet highly flexible foundation for solving these types of problems. SWIG simplifies development by largely automating the task of scripting language integration--allowing developers and users to focus on more important problems.
Although SWIG was originally developed for scientific applications, it has since evolved into a general purpose tool that is used in a wide variety of applications--in fact almost anything where C/C++ programming is involved.
Since SWIG was released in 1996, its user base and applicability has continued to grow. Although its rate of development has varied, an active development effort has continued to make improvements to the system. Today, nearly a dozen developers are working to create SWIG-2.0---a system that aims to provide wrapping support for nearly all of the ANSI C++ standard and approximately ten target languages including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby, and Tcl.
For several years, the most stable version of SWIG has been release 1.1p5. Starting with version 1.3, a new version numbering scheme has been adopted. Odd version numbers (1.3, 1.5, etc.) represent development versions of SWIG. Even version numbers (1.4, 1.6, etc.) represent stable releases. Currently, developers are working to create a stable SWIG-2.0 release. Don't let the development status of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5.
The official location of SWIG related material is
This site contains the latest version of the software, users guide, and information regarding bugs, installation problems, and implementation tricks.
You can also subscribe to the swig-user mailing list by visiting the page
The mailing list often discusses some of the more technical aspects of SWIG along with information about beta releases and future work.
SVN access to the latest version of SWIG is also available. More information about this can be obtained at:
This manual assumes that you know how to write C/C++ programs and that you have at least heard of scripting languages such as Tcl, Python, and Perl. A detailed knowledge of these scripting languages is not required although some familiarity won't hurt. No prior experience with building C extensions to these languages is required---after all, this is what SWIG does automatically. However, you should be reasonably familiar with the use of compilers, linkers, and makefiles since making scripting language extensions is somewhat more complicated than writing a normal C program.
Recent SWIG releases have become significantly more capable in their C++ handling--especially support for advanced features like namespaces, overloaded operators, and templates. Whenever possible, this manual tries to cover the technicalities of this interface. However, this isn't meant to be a tutorial on C++ programming. For many of the gory details, you will almost certainly want to consult a good C++ reference. If you don't program in C++, you may just want to skip those parts of the manual.
The first few chapters of this manual describe SWIG in general and provide an overview of its capabilities. The remaining chapters are devoted to specific SWIG language modules and are self contained. Thus, if you are using SWIG to build Python interfaces, you can probably skip to that chapter and find almost everything you need to know. Caveat: we are currently working on a documentation rewrite and many of the older language module chapters are still somewhat out of date.
If you hate reading manuals, glance at the "Introduction" which contains a few simple examples. These examples contain about 95% of everything you need to know to use SWIG. After that, simply use the language-specific chapters as a reference. The SWIG distribution also comes with a large directory of examples that illustrate different topics.
If you are a previous user of SWIG, don't expect recent versions of SWIG to provide backwards compatibility. In fact, backwards compatibility issues may arise even between successive 1.3.x releases. Although these incompatibilities are regrettable, SWIG-1.3 is an active development project. The primary goal of this effort is to make SWIG better---a process that would simply be impossible if the developers are constantly bogged down with backwards compatibility issues.
On a positive note, a few incompatibilities are a small price to pay for the large number of new features that have been added---namespaces, templates, smart pointers, overloaded methods, operators, and more.
If you need to work with different versions of SWIG and backwards compatibility is an issue, you can use the SWIG_VERSION preprocessor symbol which holds the version of SWIG being executed. SWIG_VERSION is a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11). This can be used in an interface file to define different typemaps, take advantage of different features etc:
#if SWIG_VERSION >= 0x010311 /* Use some fancy new feature */ #endif
Note: The version symbol is not defined in the generated SWIG wrapper file. The SWIG preprocessor has defined SWIG_VERSION since SWIG-1.3.11.
SWIG is an unfunded project that would not be possible without the contributions of many people. Most recent SWIG development has been supported by Matthias Köppe, William Fulton, Lyle Johnson, Richard Palmer, Thien-Thi Nguyen, Jason Stewart, Loic Dachary, Masaki Fukushima, Luigi Ballabio, Sam Liddicott, Art Yerkes, Marcelo Matus, Harco de Hilster, John Lenz, and Surendra Singhi.
Historically, the following people contributed to early versions of SWIG. Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim Germann at Los Alamos National Laboratory were the first users. Patrick Tullmann at the University of Utah suggested the idea of automatic documentation generation. John Schmidt and Kurtis Bleeker at the University of Utah tested out the early versions. Chris Johnson supported SWIG's developed at the University of Utah. John Buckman, Larry Virden, and Tom Schwaller provided valuable input on the first releases and improving the portability of SWIG. David Fletcher and Gary Holt have provided a great deal of input on improving SWIG's Perl5 implementation. Kevin Butler contributed the first Windows NT port.
Although every attempt has been made to make SWIG bug-free, we are also trying to make feature improvements that may introduce bugs. To report a bug, either send mail to the SWIG developer list at the swig-devel mailing list or report a bug at the SWIG bug tracker. In your report, be as specific as possible, including (if applicable), error messages, tracebacks (if a core dump occurred), corresponding portions of the SWIG interface file used, and any important pieces of the SWIG generated wrapper code. We can only fix bugs if we know about them.
SWIG is a software development tool that simplifies the task of interfacing different languages to C and C++ programs. In a nutshell, SWIG is a compiler that takes C declarations and creates the wrappers needed to access those declarations from other languages including including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally requires no modifications to existing code and can often be used to build a usable interface in only a few minutes. Possible applications of SWIG include:
SWIG was originally designed to make it extremely easy for scientists and engineers to build extensible scientific software without having to get a degree in software engineering. Because of this, the use of SWIG tends to be somewhat informal and ad-hoc (e.g., SWIG does not require users to provide formal interface specifications as you would find in a dedicated IDL compiler). Although this style of development isn't appropriate for every project, it is particularly well suited to software development in the small; especially the research and development work that is commonly found in scientific and engineering projects.
As stated in the previous section, the primary purpose of SWIG is to simplify the task of integrating C/C++ with other programming languages. However, why would anyone want to do that? To answer that question, it is useful to list a few strengths of C/C++ programming:
Next, let's list a few problems with C/C++ programming
To address these limitations, many programmers have arrived at the conclusion that it is much easier to use different programming languages for different tasks. For instance, writing a graphical user interface may be significantly easier in a scripting language like Python or Tcl (consider the reasons why millions of programmers have used languages like Visual Basic if you need more proof). An interactive interpreter might also serve as a useful debugging and testing tool. Other languages like Java might greatly simplify the task of writing distributed computing software. The key point is that different programming languages offer different strengths and weaknesses. Moreover, it is extremely unlikely that any programming is ever going to be perfect. Therefore, by combining languages together, you can utilize the best features of each language and greatly simplify certain aspects of software development.
From the standpoint of C/C++, a lot of people use SWIG because they want to break out of the traditional monolithic C programming model which usually results in programs that resemble this:
Instead of going down that route, incorporating C/C++ into a higher level language often results in a more modular design, less code, better flexibility, and increased programmer productivity.
SWIG tries to make the problem of C/C++ integration as painless as possible. This allows you to focus on the underlying C program and using the high-level language interface, but not the tedious and complex chore of making the two languages talk to each other. At the same time, SWIG recognizes that all applications are different. Therefore, it provides a wide variety of customization features that let you change almost every aspect of the language bindings. This is the main reason why SWIG has such a large user manual ;-).
The best way to illustrate SWIG is with a simple example. Consider the following C code:
/* File : example.c */
double My_variable = 3.0;
/* Compute factorial of n */
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
/* Compute n mod m */
int my_mod(int n, int m) {
return(n % m);
}
Suppose that you wanted to access these functions and the global variable My_variable from Tcl. You start by making a SWIG interface file as shown below (by convention, these files carry a .i suffix) :
/* File : example.i */
%module example
%{
/* Put headers and other declarations here */
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
%}
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
The interface file contains ANSI C function prototypes and variable declarations. The %module directive defines the name of the module that will be created by SWIG. The %{,%} block provides a location for inserting additional code such as C header files or additional C declarations.
SWIG is invoked using the swig command. We can use this to build a Tcl module (under Linux) as follows :
unix > swig -tcl example.i unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include unix > gcc -shared example.o example_wrap.o -o example.so unix > tclsh % load ./example.so % fact 4 24 % my_mod 23 7 2 % expr $My_variable + 4.5 7.5 %
The swig command produced a new file called example_wrap.c that should be compiled along with the example.c file. Most operating systems and scripting languages now support dynamic loading of modules. In our example, our Tcl module has been compiled into a shared library that can be loaded into Tcl. When loaded, Tcl can now access the functions and variables declared in the SWIG interface. A look at the file example_wrap.c reveals a hideous mess. However, you almost never need to worry about it.
Now, let's turn these functions into a Perl5 module. Without making any changes type the following (shown for Solaris):
unix > swig -perl5 example.i unix > gcc -c example.c example_wrap.c \ -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE unix > ld -G example.o example_wrap.o -o example.so # This is for Solaris unix > perl5.003 use example; print example::fact(4), "\n"; print example::my_mod(23,7), "\n"; print $example::My_variable + 4.5, "\n"; <ctrl-d> 24 2 7.5 unix >
Finally, let's build a module for Python (shown for Irix).
unix > swig -python example.i unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0 unix > gcc -shared example.o example_wrap.o -o _example.so unix > python Python 2.0 (#6, Feb 21 2001, 13:29:45) [GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2 Type "copyright", "credits" or "license" for more information. >>> import example >>> example.fact(4) 24 >>> example.my_mod(23,7) 2 >>> example.cvar.My_variable + 4.5 7.5
To the truly lazy programmer, one may wonder why we needed the extra interface file at all. As it turns out, you can often do without it. For example, you could also build a Perl5 module by just running SWIG on the C header file and specifying a module name as follows
unix > swig -perl5 -module example example.h unix > gcc -c example.c example_wrap.c \ -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE unix > ld -G example.o example_wrap.o -o example.so unix > perl5.003 use example; print example::fact(4), "\n"; print example::my_mod(23,7), "\n"; print $example::My_variable + 4.5, "\n"; <ctrl-d> 24 2 7.5
A primary goal of the SWIG project is to make the language binding process extremely easy. Although a few simple examples have been shown, SWIG is quite capable in supporting most of C++. Some of the major features include:
Currently, the only major C++ feature not supported is nested classes--a limitation that will be removed in a future release.
It is important to stress that SWIG is not a simplistic C++ lexing tool like several apparently similar wrapper generation tools. SWIG not only parses C++, it implements the full C++ type system and it is able to understand C++ semantics. SWIG generates its wrappers with full knowledge of this information. As a result, you will find SWIG to be just as capable of dealing with nasty corner cases as it is in wrapping simple C++ code. In fact, SWIG is able handle C++ code that stresses the very limits of many C++ compilers.
When used as intended, SWIG requires minimal (if any) modification to existing C or C++ code. This makes SWIG extremely easy to use with existing packages and promotes software reuse and modularity. By making the C/C++ code independent of the high level interface, you can change the interface and reuse the code in other applications. It is also possible to support different types of interfaces depending on the application.
SWIG is a command line tool and as such can be incorporated into any build system that supports invoking external tools/compilers. SWIG is most commonly invoked from within a Makefile, but is also known to be invoked from from popular IDEs such as Microsoft Visual Studio.
If you are using the GNU Autotools ( Autoconf/ Automake / Libtool) to configure SWIG use in your project, the SWIG Autoconf macros can be used. The primary macro is ac_pkg_swig, see http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html. The ac_python_devel macro is also helpful for generating Python extensions. See the Autoconf Macro Archive for further information on this and other Autoconf macros.
There is growing support for SWIG in some build tools, for example CMake is a cross-platform, open-source build manager with built in support for SWIG. CMake can detect the SWIG executable and many of the target language libraries for linking against. CMake knows how to build shared libraries and loadable modules on many different operating systems. This allows easy cross platform SWIG development. It also can generate the custom commands necessary for driving SWIG from IDE's and makefiles. All of this can be done from a single cross platform input file. The following example is a CMake input file for creating a python wrapper for the SWIG interface file, example.i:
# This is a CMake example for Python
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(example python example.i example.cxx)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})
The above example will generate native build files such as makefiles, nmake files and Visual Studio projects which will invoke SWIG and compile the generated C++ files into _example.so (UNIX) or _example.dll (Windows).
SWIG is designed to produce working code that needs no hand-modification (in fact, if you look at the output, you probably won't want to modify it). You should think of your target language interface being defined entirely by the input to SWIG, not the resulting output file. While this approach may limit flexibility for hard-core hackers, it allows others to forget about the low-level implementation details.
No, this isn't a special section on the sorry state of world politics. However, it may be useful to know that SWIG was written with a certain "philosophy" about programming---namely that programmers are smart and that tools should just stay out of their way. Because of that, you will find that SWIG is extremely permissive in what it lets you get away with. In fact, you can use SWIG to go well beyond "shooting yourself in the foot" if dangerous programming is your goal. On the other hand, this kind of freedom may be exactly what is needed to work with complicated and unusual C/C++ applications.
Ironically, the freedom that SWIG provides is countered by an extremely conservative approach to code generation. At it's core, SWIG tries to distill even the most advanced C++ code down to a small well-defined set of interface building techniques based on ANSI C programming. Because of this, you will find that SWIG interfaces can be easily compiled by virtually every C/C++ compiler and that they can be used on any platform. Again, this is an important part of staying out of the programmer's way----the last thing any developer wants to do is to spend their time debugging the output of a tool that relies on non-portable or unreliable programming features.
This chapter describes SWIG usage on Microsoft Windows. Installing SWIG and running the examples is covered as well as building the SWIG executable. Usage within the Unix like environments MinGW and Cygwin is also detailed.
SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP. If you want to build your own swig.exe have a look at Building swig.exe on Windows.
Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output. The Examples directory has a few Visual C++ project files (.dsp files). These were produced by Visual C++ 6, although they should also work in Visual C++ 5. Later versions of Visual Studio should also be able to open and convert these project files. The C# examples come with .NET 2003 solution (.sln) and project files instead of Visual C++ 6 project files. The project files have been set up to execute SWIG in a custom build rule for the SWIG interface (.i) file. Alternatively run the examples using Cygwin.
More information on each of the examples is available with the examples distributed with SWIG (Examples/index.html).
Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Most languages require some environment variables to be set before running Visual C++. Note that Visual C++ must be re-started to pick up any changes in environment variables. Open up an example .dsp file, Visual C++ will create a workspace for you (.dsw file). Ensure the Release build is selected then do a Rebuild All from the Build menu. The required environment variables are displayed with their current values.
The list of required environment variables for each module language is also listed below. They are usually set from the Control Panel and System properties, but this depends on which flavour of Windows you are running. If you don't want to use environment variables then change all occurrences of the environment variables in the .dsp files with hard coded values. If you are interested in how the project files are set up there is explanatory information in some of the language module's documentation.
The C# examples do not require any environment variables to be set as a C# project file is included. Just open up the .sln solution file in Visual Studio .NET 2003 or later, select Release Build, and do a Rebuild All from the Build menu. The accompanying C# and C++ project files are automatically used by the solution file.
JAVA_INCLUDE : Set this to the directory containing
jni.h
JAVA_BIN : Set this to the bin directory containing
javac.exe
Example using JDK1.3:
JAVA_INCLUDE: D:\jdk1.3\include
JAVA_BIN: D:\jdk1.3\bin
PERL5_INCLUDE : Set this to the directory containing
perl.h
PERL5_LIB : Set this to the Perl library including
path for linking
Example using nsPerl 5.004_04:
PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE
PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib
PYTHON_INCLUDE : Set this to the directory that
contains python.h
PYTHON_LIB : Set this to the python library
including path for linking
Example using Python 2.1.1:
PYTHON_INCLUDE: D:\python21\include
PYTHON_LIB: D:\python21\libs\python21.lib
TCL_INCLUDE : Set this to the directory containing
tcl.h
TCL_LIB : Set this to the TCL library including
path for linking
Example using ActiveTcl 8.3.3.3
TCL_INCLUDE: D:\tcl\include
TCL_LIB: D:\tcl\lib\tcl83.lib
R_INCLUDE : Set this to the directory containing R.h
R_LIB : Set this to the R library (Rdll.lib)
including path for linking. The library needs to be built as described
in the R README.packages file (the pexports.exe approach is the
easiest).
Example using R 2.5.1:
R_INCLUDE: C:\Program Files\R\R-2.5.1\include
R_LIB: C:\Program Files\R\R-2.5.1\bin\Rdll.lib
RUBY_INCLUDE : Set this to the directory containing
ruby.h
RUBY_LIB : Set this to the ruby library including
path for linking
Example using Ruby 1.6.4:
RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32
RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib
If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.
SWIG can also be compiled and run using Cygwin or MinGW which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied.
If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below. This is not necessary to use the supplied swig.exe. This information is provided for those that want to modify the SWIG source code in a Windows environment. Normally this is not needed, so most people will want to ignore this section.
The short abbreviated instructions follow...
The step by step instructions to download and install MinGW and MSYS, then download and build the latest version of SWIG from SVN follow... Note that the instructions for obtaining SWIG from SVN are also online at SWIG SVN.
Pitfall note: Execute the steps in the order shown and don't use spaces in path names. In fact it is best to use the default installation directories.
cd / tar -jxf msys-automake-1.8.2.tar.bz2 tar -jxf msys-autoconf-2.59.tar.bz2 tar -zxf bison-2.0-MSYS.tar.gz
mkdir /usr/src cd /usr/src svn co https://swig.svn.sourceforge.net/svnroot/swig/trunk swig
cd /usr/src/swig ./autogen.sh ./configure make
Note that SWIG can also be built using Cygwin. However, SWIG will then require the Cygwin DLL when executing. Follow the Unix instructions in the README file in the SWIG root directory. Note that the Cygwin environment will also allow one to regenerate the autotool generated files which are supplied with the release distribution. These files are generated using the autogen.sh script and will only need regenerating in circumstances such as changing the build system.
If you don't want to install Cygwin or MinGW, use a different compiler to build SWIG. For example, all the source code files can be added to a Visual C++ project file in order to build swig.exe from the Visual C++ IDE.
The examples and test-suite work as successfully on Cygwin as on any other Unix operating system. The modules which are known to work are Python, Tcl, Perl, Ruby, Java and C#. Follow the Unix instructions in the README file in the SWIG root directory to build the examples.
A common problem when using SWIG on Windows are the Microsoft function calling conventions which are not in the C++ standard. SWIG parses ISO C/C++ so cannot deal with proprietary conventions such as __declspec(dllimport), __stdcall etc. There is a Windows interface file, windows.i, to deal with these calling conventions though. The file also contains typemaps for handling commonly used Windows specific types such as __int64, BOOL , DWORD etc. Include it like you would any other interface file, for example:
%include <windows.i> __declspec(dllexport) ULONG __stdcall foo(DWORD, __int32);
This chapter provides a brief overview of scripting language extension programming and the mechanisms by which scripting language interpreters access C and C++ code.
When a scripting language is used to control a C program, the resulting system tends to look as follows:

In this programming model, the scripting language interpreter is used for high level control whereas the underlying functionality of the C/C++ program is accessed through special scripting language "commands." If you have ever tried to write your own simple command interpreter, you might view the scripting language approach to be a highly advanced implementation of that. Likewise, If you have ever used a package such as MATLAB or IDL, it is a very similar model--the interpreter executes user commands and scripts. However, most of the underlying functionality is written in a low-level language like C or Fortran.
The two-language model of computing is extremely powerful because it exploits the strengths of each language. C/C++ can be used for maximal performance and complicated systems programming tasks. Scripting languages can be used for rapid prototyping, interactive debugging, scripting, and access to high-level data structures such associative arrays.
Scripting languages are built around a parser that knows how to execute commands and scripts. Within this parser, there is a mechanism for executing commands and accessing variables. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is usually possible to add new commands and variables. To do this, most languages define a special API for adding new commands. Furthermore, a special foreign function interface defines how these new commands are supposed to hook into the interpreter.
Typically, when you add a new command to a scripting interpreter you need to do two things; first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.
Suppose you have an ordinary C function like this :
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :
As an example, the Tcl wrapper function for the fact() function above example might look like the following :
int wrap_fact(ClientData clientData, Tcl_Interp *interp,
int argc, char *argv[]) {
int result;
int arg0;
if (argc != 2) {
interp->result = "wrong # args";
return TCL_ERROR;
}
arg0 = atoi(argv[1]);
result = fact(arg0);
sprintf(interp->result,"%d", result);
return TCL_OK;
}
Once you have created a wrapper function, the final step is to tell the scripting language about the new function. This is usually done in an initialization function called by the language when the module is loaded. For example, adding the above function to the Tcl interpreter requires code like the following :
int Wrap_Init(Tcl_Interp *interp) {
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
When executed, Tcl will now have a new command called "fact " that you can use like any other Tcl command.
Although the process of adding a new function to Tcl has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. Only the specific details are different.
Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:
double Foo = 3.5;
It might be nice to access it from a script as follows (shown for Perl):
$a = $Foo * 2.3; # Evaluation $Foo = $a + 2.0; # Assignment
To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.
In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as $Foo might implicitly call the get function. Similarly, typing $Foo = 4 would call the underlying set function to change the value.
In many cases, a C program or library may define a large collection of constants. For example:
#define RED 0xff0000 #define BLUE 0x0000ff #define GREEN 0x00ff00
To make constants available, their values can be stored in scripting language variables such as $RED, $BLUE, and $GREEN. Virtually all scripting languages provide C functions for creating variables so installing constants is usually a trivial exercise.
Although scripting languages have no trouble accessing simple functions and variables, accessing C/C++ structures and classes present a different problem. This is because the implementation of structures is largely related to the problem of data representation and layout. Furthermore, certain language features are difficult to map to an interpreter. For instance, what does C++ inheritance mean in a Perl interface?
The most straightforward technique for handling structures is to implement a collection of accessor functions that hide the underlying representation of a structure. For example,
struct Vector {
Vector();
~Vector();
double x,y,z;
};
can be transformed into the following set of functions :
Vector *new_Vector(); void delete_Vector(Vector *v); double Vector_x_get(Vector *v); double Vector_y_get(Vector *v); double Vector_z_get(Vector *v); void Vector_x_set(Vector *v, double x); void Vector_y_set(Vector *v, double y); void Vector_z_set(Vector *v, double z);
Now, from an interpreter these function might be used as follows:
% set v [new_Vector] % Vector_x_set $v 3.5 % Vector_y_get $v % delete_Vector $v % ...
Since accessor functions provide a mechanism for accessing the internals of an object, the interpreter does not need to know anything about the actual representation of a Vector.
In certain cases, it is possible to use the low-level accessor functions to create a proxy class, also known as a shadow class. A proxy class is a special kind of object that gets created in a scripting language to access a C/C++ class (or struct) in a way that looks like the original structure (that is, it proxies the real C++ class). For example, if you have the following C definition :
class Vector {
public:
Vector();
~Vector();
double x,y,z;
};
A proxy classing mechanism would allow you to access the structure in a more natural manner from the interpreter. For example, in Python, you might want to do this:
>>> v = Vector() >>> v.x = 3 >>> v.y = 4 >>> v.z = -13 >>> ... >>> del v
Similarly, in Perl5 you may want the interface to work like this:
$v = new Vector;
$v->{x} = 3;
$v->{y} = 4;
$v->{z} = -13;
Finally, in Tcl :
Vector v v configure -x 3 -y 4 -z 13
When proxy classes are used, two objects are at really work--one in the scripting language, and an underlying C/C++ object. Operations affect both objects equally and for all practical purposes, it appears as if you are simply manipulating a C/C++ object.
The final step in using a scripting language with your C/C++ application is adding your extensions to the scripting language itself. There are two primary approaches for doing this. The preferred technique is to build a dynamically loadable extension in the form a shared library. Alternatively, you can recompile the scripting language interpreter with your extensions added to it.
To create a shared library or DLL, you often need to look at the manual pages for your compiler and linker. However, the procedure for a few common machines is shown below:
# Build a shared library for Solaris gcc -c example.c example_wrap.c -I/usr/local/include ld -G example.o example_wrap.o -o example.so # Build a shared library for Linux gcc -fpic -c example.c example_wrap.c -I/usr/local/include gcc -shared example.o example_wrap.o -o example.so # Build a shared library for Irix gcc -c example.c example_wrap.c -I/usr/local/include ld -shared example.o example_wrap.o -o example.so
To use your shared library, you simply use the corresponding command in the scripting language (load, import, use, etc...). This will import your module and allow you to start using it. For example:
% load ./example.so % fact 4 24 %
When working with C++ codes, the process of building shared libraries may be more complicated--primarily due to the fact that C++ modules may need additional code in order to operate correctly. On many machines, you can build a shared C++ module by following the above procedures, but changing the link line to the following :
c++ -shared example.o example_wrap.o -o example.so
When building extensions as shared libraries, it is not uncommon for your extension to rely upon other shared libraries on your machine. In order for the extension to work, it needs to be able to find all of these libraries at run-time. Otherwise, you may get an error such as the following :
>>> import graph
Traceback (innermost last):
File "<stdin>", line 1, in ?
File "/home/sci/data1/beazley/graph/graph.py", line 2, in ?
import graphc
ImportError: 1101:/home/sci/data1/beazley/bin/python: rld: Fatal Error: cannot
successfully map soname 'libgraph.so' under any of the filenames /usr/lib/libgraph.so:/
lib/libgraph.so:/lib/cmplrs/cc/libgraph.so:/usr/lib/cmplrs/cc/libgraph.so:
>>>
What this error means is that the extension module created by SWIG depends upon a shared library called "libgraph.so" that the system was unable to locate. To fix this problem, there are a few approaches you can take.
With static linking, you rebuild the scripting language interpreter with extensions. The process usually involves compiling a short main program that adds your customized commands to the language and starts the interpreter. You then link your program with a library to produce a new scripting language executable.
Although static linking is supported on all platforms, this is not the preferred technique for building scripting language extensions. In fact, there are very few practical reasons for doing this--consider using shared libraries instead.