This chapter describes the problem of using SWIG in programs where you want to create a collection of modules.
The runtime functions are private to each SWIG-generated module. That is, the runtime functions are declared with "static" linkage and are visible only to the wrapper functions defined in that module. The only problem with this approach is that when more than one SWIG module is used in the same application, those modules often need to share type information. This is especially true for C++ programs where SWIG must collect and share information about inheritance relationships that cross module boundaries.
To solve the problem of sharing information across modules, a pointer to the type information is stored in a global variable in the target language namespace. During module initialization, type information is loaded into the global data structure of type information from all modules.
This can present a problem with threads. If two modules try and load at the same time, the type information can become corrupt. SWIG currently does not provide any locking, and if you use threads, you must make sure that modules are loaded serially. Be careful if you use threads and the automatic module loading that some scripting languages provide. One solution is to load all modules before spawning any threads.
As described in The run-time type checker, the functions SWIG_TypeQuery, SWIG_NewPointerObj, and others sometimes need to be called. Calling these functions from a typemap is supported, since the typemap code is embedded into the _wrap.c file, which has those declerations available. If you need to call the SWIG run-time functions from another C file, there are three headers you need to include. They are located in the Lib directory in the SWIG source, or wherever the SWIG Library was installed. You can see the current library path by running swig -swiglib.
#include <swigrun.swg> #include <python/pyrun.swg> /* Or other header, see below */ #include <runtime.swg>
After including these three headers, your code should be able to call SWIG_TypeQuery, SWIG_NewPointerObj, SWIG_ConvertPtr and others. The exact argument paramaters for these functions might differ between language modules; please check the language module chapters for more information.
Inside these headers the functions are declared static and are included inline into the file, and thus the file does not need to be linked against any SWIG libraries or code (you might still need to link against the language libraries like libpython-2.3). Data is shared between this file and the _wrap.c files through a global variable in the wrapping language. It is also possible to copy these three header files into your own package for distribution along with the generated wrapper files, so that you can distribute a package that can be compiled without SWIG installed (this works because the header files are self contained, and do not need to link with anything).
The headers that should be included in place of the #include <python/pyrun.swg> for the different language modules are:
Using multiple modules with the %import directive is the most common approach to modularising large projects. In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file. There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options and features.
-fcompact
-fvirtual
This command line option will remove the generation of superfluous virtual method wrappers.
Consider the following inheritance hierarchy:
struct Base {
virtual void method();
...
};
struct Derived : Base {
virtual void method();
...
};
Normally wrappers are generated for both methods, whereas this command line option will suppress the generation of a wrapper for Derived::method.
Normal polymorphic behaviour remains as Derived::method will still be called should you have
a Derived instance and call the wrapper for Base::method.
%feature("compactdefaultargs")
This feature can reduce the number of wrapper methods when wrapping methods with default arguments. The section on default arguments discusses the feature and it's limitations.