mirror of https://github.com/swig/swig
260 lines
10 KiB
HTML
260 lines
10 KiB
HTML
<!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>
|