| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <title>Working with Modules</title> |
| <link rel="stylesheet" type="text/css" href="style.css"> |
| </head> |
| |
| <body bgcolor="#ffffff"> |
| <H1><a name="Modules"></a>15 Working with Modules</H1> |
| <!-- INDEX --> |
| <div class="sectiontoc"> |
| <ul> |
| <li><a href="#Modules_nn1">Basics</a> |
| <li><a href="#Modules_nn2">The SWIG runtime code</a> |
| <li><a href="#external_run_time">External access to the runtime</a> |
| <li><a href="#Modules_nn4">A word of caution about static libraries</a> |
| <li><a href="#Modules_nn5">References</a> |
| <li><a href="#Modules_nn6">Reducing the wrapper file size</a> |
| </ul> |
| </div> |
| <!-- INDEX --> |
| |
| |
| |
| <p> |
| When first working with SWIG, users commonly start by creating a |
| single module. That is, you might define a single SWIG interface that |
| wraps some set of C/C++ code. You then compile all of the generated |
| wrapper code into a module and use it. For large applications, however, |
| this approach is problematic---the size of the generated wrapper code |
| can be rather large. Moreover, it is probably easier to manage the |
| target language interface when it is broken up into smaller pieces. |
| </p> |
| |
| <p> |
| This chapter describes the problem of using SWIG in programs |
| where you want to create a collection of modules. |
| </p> |
| |
| <H2><a name="Modules_nn1"></a>15.1 Basics</H2> |
| |
| |
| <p> |
| The basic usage case with multiple modules is when modules do not have |
| cross-references (ie. when wrapping multiple independent C APIs). In that case, |
| swig input files should just work out of the box - you simply create multiple |
| wrapper .cxx files, link them into your application, and insert/load each in the |
| scripting language runtime as you would do for the single module case. |
| </p> |
| |
| <p> |
| A bit more complex is the case in which modules need to share information. |
| For example, when one module extends the class of the another by deriving from |
| it: |
| </p> |
| |
| <div class="code"><pre> |
| %module base |
| |
| %inline %{ |
| class base { |
| public: |
| int foo(void); |
| }; |
| %} |
| </pre></div> |
| |
| <div class="code"><pre> |
| %module derived |
| |
| %import "base.i" |
| |
| %inline %{ |
| class derived : public base { |
| public: |
| int bar(void); |
| }; |
| %} |
| </pre></div> |
| |
| <p>To create the wrapper properly, module <tt>derived</tt> needs to know the |
| <tt>base</tt> class and that it's interface is covered in another module. The |
| line <tt>%import "base.i"</tt> lets SWIG know exactly that. The common mistake here is |
| to <tt>%import</tt> the <tt>.h</tt> file instead of the <tt>.i</tt>, which sadly won't do the trick. Another issue |
| to take care of is that multiple dependent wrappers should not be linked/loaded |
| in parallel from multiple threads as SWIG provides no locking - for more on that |
| issue, read on.</p> |
| |
| <H2><a name="Modules_nn2"></a>15.2 The SWIG runtime code</H2> |
| |
| |
| <p> |
| Many of SWIG's target languages generate a set of functions commonly known as |
| the "SWIG runtime." These functions are primarily related to the runtime type |
| system which checks pointer types and performs other tasks such as proper |
| casting of pointer values in C++. As a general rule, the statically typed target |
| languages, such as Java, use the language's built in static type checking and |
| have no need for a SWIG runtime. All the dynamically typed / interpreted |
| languages rely on the SWIG runtime. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| There are a few trade offs with this approach. This type information is global |
| across all SWIG modules loaded, and can cause type conflicts between modules |
| that were not designed to work together. To solve this approach, the SWIG |
| runtime code uses a define SWIG_TYPE_TABLE to provide a unique type table. This |
| behavior can be enabled when compiling the generated _wrap.cxx or _wrap.c file |
| by adding -DSWIG_TYPE_TABLE=myprojectname to the command line argument. |
| </p> |
| |
| <p> |
| Then, only modules compiled with SWIG_TYPE_TABLE set to myprojectname will share |
| type information. So if your project has three modules, all three should be |
| compiled with -DSWIG_TYPE_TABLE=myprojectname, and then these three modules will |
| share type information. But any other project's types will not interfere or |
| clash with the types in your module. |
| </p> |
| |
| <p> |
| Another issue relating to the global type table is thread safety. 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, or use SWIG_TYPE_TABLE to |
| separate type tables so they do not clash with each other. |
| </p> |
| |
| <p> |
| Lastly, SWIG uses a #define SWIG_RUNTIME_VERSION, located in Lib/swigrun.swg and |
| near the top of every generated module. This number gets incremented when the |
| data structures change, so that SWIG modules generated with different versions |
| can peacefully coexist. So the type structures are separated by the |
| (SWIG_TYPE_TABLE, SWIG_RUNTIME_VERSION) pair, where by default SWIG_TYPE_TABLE |
| is empty. Only modules compiled with the same pair will share type information. |
| </p> |
| |
| <H2><a name="external_run_time"></a>15.3 External access to the runtime</H2> |
| |
| |
| <p>As described in <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>, |
| the functions <tt>SWIG_TypeQuery</tt>, <tt>SWIG_NewPointerObj</tt>, and others sometimes need |
| to be called. Calling these functions from a typemap is supported, since the typemap code |
| is embedded into the <tt>_wrap.c</tt> file, which has those declarations available. If you need |
| to call the SWIG run-time functions from another C file, there is one header you need |
| to include. To generate the header that needs to be included, run the following command: |
| |
| <div class="shell"><pre> |
| $ swig -python -external-runtime <filename> |
| </pre></div> |
| |
| <p>The filename argument is optional and if it is not passed, then the default filename will |
| be something like <tt>swigpyrun.h</tt>, depending on the language. This header file should |
| be treated like any of the other _wrap.c output files, and should be regenerated when the |
| _wrap files are. After including this header, your code will be able to call <tt>SWIG_TypeQuery</tt>, |
| <tt>SWIG_NewPointerObj</tt>, <tt>SWIG_ConvertPtr</tt> and others. The exact argument parameters |
| for these functions might differ between language modules; please check the language module chapters |
| for more information.</p> |
| |
| <p>Inside this header 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 scripting language. It is also |
| possible to copy this header file along with the generated wrapper files into your own package, |
| so that you can distribute a package that can be compiled without SWIG installed (this works |
| because the header file is self-contained, and does not need to link with anything).</p> |
| |
| <p> |
| This header will also use the -DSWIG_TYPE_TABLE described above, so when |
| compiling any code which includes the generated header file should define the |
| SWIG_TYPE_TABLE to be the same as the module whose types you are trying to |
| access. |
| </p> |
| |
| <H2><a name="Modules_nn4"></a>15.4 A word of caution about static libraries</H2> |
| |
| |
| <p> |
| When working with multiple SWIG modules, you should take care not to use static |
| libraries. For example, if you have a static library <tt>libfoo.a</tt> and you link a collection |
| of SWIG modules with that library, each module will get its own private copy of the library code inserted |
| into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program |
| behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries. |
| </p> |
| |
| <H2><a name="Modules_nn5"></a>15.5 References</H2> |
| |
| |
| <p> |
| Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult |
| an outside reference. John Levine's "Linkers and Loaders" is highly recommended. |
| </p> |
| |
| <H2><a name="Modules_nn6"></a>15.6 Reducing the wrapper file size</H2> |
| |
| |
| <p> |
| Using multiple modules with the <tt>%import</tt> 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. |
| </p> |
| |
| <p> |
| <b>-fcompact</b><br> |
| This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file. |
| It simply removes blank lines and joins lines of code together. |
| This is useful for compilers that have a maximum file size that can be handled. |
| </p> |
| |
| <p> |
| <b>-fvirtual</b><br> |
| This command line option will remove the generation of superfluous virtual method wrappers. |
| Consider the following inheritance hierarchy: |
| </p> |
| |
| <div class="code"> |
| <pre> |
| struct Base { |
| virtual void method(); |
| ... |
| }; |
| |
| struct Derived : Base { |
| virtual void method(); |
| ... |
| }; |
| </pre> |
| </div> |
| |
| <p> |
| Normally wrappers are generated for both methods, whereas this command line option will suppress the generation of a wrapper for <tt>Derived::method</tt>. |
| Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have |
| a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>. |
| </p> |
| |
| <p> |
| <b>%feature("compactdefaultargs")</b><br> |
| This feature can reduce the number of wrapper methods when wrapping methods with default arguments. The section on <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> discusses the feature and its limitations. |
| </p> |
| |
| </body> |
| </html> |