Update the documentation for new runtime type linking.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6389 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
1ea4adbcd4
commit
02cffc8047
5 changed files with 47 additions and 166 deletions
|
|
@ -9,10 +9,9 @@
|
|||
<!-- INDEX -->
|
||||
<ul>
|
||||
<li><a href="#Modules_nn2">The SWIG runtime code</a>
|
||||
<li><a href="#Modules_nn3">Compiling Multiple SWIG modules</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>
|
||||
<li><a href="#Modules_nn3">A word of caution about static libraries</a>
|
||||
<li><a href="#Modules_nn4">References</a>
|
||||
<li><a href="#Modules_nn5">Reducing the wrapper file size</a>
|
||||
</ul>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
|
@ -44,12 +43,10 @@ have no need for a SWIG runtime. All the dynamically typed / interpreted
|
|||
languages rely on the SWIG runtime.
|
||||
|
||||
<p>
|
||||
By default, the runtime functions are private to each SWIG-generated
|
||||
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. If two completely different SWIG modules are loaded, this
|
||||
presents no problem---each module uses its own private runtime code.
|
||||
The only problem with this approach is that when more than one SWIG
|
||||
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
|
||||
|
|
@ -57,116 +54,21 @@ relationships that cross module boundaries.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
To solve the problem of sharing information across modules, the
|
||||
SWIG runtime functions need to be exposed in a way that allows data to
|
||||
be shared between modules. The next section describes how to do that.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn3"></a>15.2 Compiling Multiple SWIG modules</H2>
|
||||
|
||||
|
||||
Suppose that you have three SWIG interface files A.i, B.i, and C.i
|
||||
and suppose that these modules interact with each other. To make this work,
|
||||
there are two approaches you can take:
|
||||
|
||||
<p>
|
||||
<b>Option 1:</b> Designate one module to provide the runtime code
|
||||
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>
|
||||
With this option, one of the modules is designated as providing the runtime
|
||||
environment. This is done with the <tt>-runtime</tt> option like this:
|
||||
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.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% swig -runtime -c++ -python A.i
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The other modules are then compiled without runtime support. This is done by
|
||||
supplying the <tt>-noruntime</tt> option like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% swig -noruntime -c++ -python B.i
|
||||
% swig -noruntime -c++ -python C.i
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
To use the modules, you compile and link everything as before, but you
|
||||
need to make sure that module A is loaded before all of the other
|
||||
modules are used---otherwise you will get unresolved symbols.
|
||||
|
||||
<p>
|
||||
Now, the bad news: This approach may or may not work depending on the platform you
|
||||
are using, what target language you are using, and the way that shared libraries work
|
||||
on the system. On many systems, the symbols contained in dynamically loaded modules
|
||||
are private. Therefore, even though module A provides the runtime code, the other modules
|
||||
won't be able to find it. You'll know if this is the case if you try to load the other modules
|
||||
and you get errors about unresolved SWIG_* functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Option 2: Build a runtime library</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The second way to work with multiple modules is to create a special runtime library module.
|
||||
To do this, you first need to create an empty SWIG interface file, say swigrun.i, containing
|
||||
just the %module directive, for example:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
%module swigrun
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Next, build a runtime library like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% swig -runtime -python swigrun.i
|
||||
% # Build a shared library --- this is different on every machine! (shown for Linux)
|
||||
% gcc -fpic swigrun_wrap.c -o swigrun_wrap.o
|
||||
% gcc -shared swigrun_wrap.o -o libswigrunpy.so
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
Now, you compile all of the normal SWIG modules using the <tt>-noruntime</tt> option:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% swig -noruntime -c++ -python A.i
|
||||
% swig -noruntime -c++ -python B.i
|
||||
% swig -noruntime -c++ -python C.i
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Finally, when linking the dynamically loadable modules, you need to link again the special
|
||||
runtime library above. For example (Linux) :
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% g++ -shared A_wrap.o -L. -lswigrunpy -o _A.so
|
||||
% g++ -shared B_wrap.o -L. -lswigrunpy -o _B.so
|
||||
% g++ -shared C_wrap.o -L. -lswigrunpy -o _C.so
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Again, all of the details will vary depending on what compiler you use, the platform, target language,
|
||||
and so forth. The key point is that the runtime needs to be contained in a shared/dynamic library (DLL) and
|
||||
you need to link all of the modules against that library.
|
||||
|
||||
<p>
|
||||
When you use the modules created using this technique, the runtime code will be automatically loaded
|
||||
when the modules are imported. Moreover, since all of the modules are linked against the same runtime
|
||||
library, they will share that code.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn4"></a>15.3 A word of caution about static libraries</H2>
|
||||
<H2><a name="Modules_nn3"></a>15.2 A word of caution about static libraries</H2>
|
||||
|
||||
|
||||
When working with multiple SWIG modules, you should take care not to use static
|
||||
|
|
@ -175,13 +77,13 @@ of SWIG modules with that library, each module will get its own private copy of
|
|||
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 libaries.
|
||||
|
||||
<H2><a name="Modules_nn5"></a>15.4 References</H2>
|
||||
<H2><a name="Modules_nn4"></a>15.3 References</H2>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
<H2><a name="Modules_nn6"></a>15.5 Reducing the wrapper file size</H2>
|
||||
<H2><a name="Modules_nn5"></a>15.4 Reducing the wrapper file size</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue