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.
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:
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.struct Base { virtual void method(); ... }; struct Derived : Base { virtual void 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.