Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>Working with Modules</title> | |
5 | <link rel="stylesheet" type="text/css" href="style.css"> | |
6 | </head> | |
7 | ||
8 | <body bgcolor="#ffffff"> | |
9 | <H1><a name="Modules"></a>15 Working with Modules</H1> | |
10 | <!-- INDEX --> | |
11 | <div class="sectiontoc"> | |
12 | <ul> | |
13 | <li><a href="#Modules_nn2">The SWIG runtime code</a> | |
14 | <li><a href="#external_run_time">External access to the runtime</a> | |
15 | <li><a href="#Modules_nn4">A word of caution about static libraries</a> | |
16 | <li><a href="#Modules_nn5">References</a> | |
17 | <li><a href="#Modules_nn6">Reducing the wrapper file size</a> | |
18 | </ul> | |
19 | </div> | |
20 | <!-- INDEX --> | |
21 | ||
22 | ||
23 | ||
24 | <p> | |
25 | When first working with SWIG, users commonly start by creating a | |
26 | single module. That is, you might define a single SWIG interface that | |
27 | wraps some set of C/C++ code. You then compile all of the generated | |
28 | wrapper code into a module and use it. For large applications, however, | |
29 | this approach is problematic---the size of the generated wrapper code | |
30 | can be rather large. Moreover, it is probably easier to manage the | |
31 | target language interface when it is broken up into smaller pieces. | |
32 | </p> | |
33 | ||
34 | <p> | |
35 | This chapter describes the problem of using SWIG in programs | |
36 | where you want to create a collection of modules. | |
37 | </p> | |
38 | ||
39 | <H2><a name="Modules_nn2"></a>15.1 The SWIG runtime code</H2> | |
40 | ||
41 | ||
42 | <p> | |
43 | Many of SWIG's target languages generate a set of functions | |
44 | commonly known as the "SWIG runtime." These functions are | |
45 | primarily related to the runtime type system which checks pointer | |
46 | types and performs other tasks such as proper casting of pointer | |
47 | values in C++. As a general rule, the statically typed target languages, | |
48 | such as Java, use the language's built in static type checking and | |
49 | have no need for a SWIG runtime. All the dynamically typed / interpreted | |
50 | languages rely on the SWIG runtime. | |
51 | </p> | |
52 | ||
53 | <p> | |
54 | The runtime functions are private to each SWIG-generated | |
55 | module. That is, the runtime functions are declared with "static" | |
56 | linkage and are visible only to the wrapper functions defined in that | |
57 | module. The only problem with this approach is that when more than one SWIG | |
58 | module is used in the same application, those modules often need to | |
59 | share type information. This is especially true for C++ programs | |
60 | where SWIG must collect and share information about inheritance | |
61 | relationships that cross module boundaries. | |
62 | </p> | |
63 | ||
64 | <p> | |
65 | To solve the problem of sharing information across modules, a pointer to the | |
66 | type information is stored in a global variable in the target language namespace. | |
67 | During module initialization, type information is loaded into the global data | |
68 | structure of type information from all modules. | |
69 | </p> | |
70 | ||
71 | <p> | |
72 | This can present a problem with threads. If two modules try and load at the same | |
73 | time, the type information can become corrupt. SWIG currently does not provide any | |
74 | locking, and if you use threads, you must make sure that modules are loaded serially. | |
75 | Be careful if you use threads and the automatic module loading that some scripting | |
76 | languages provide. One solution is to load all modules before spawning any threads. | |
77 | </p> | |
78 | ||
79 | <H2><a name="external_run_time"></a>15.2 External access to the runtime</H2> | |
80 | ||
81 | ||
82 | <p>As described in <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>, | |
83 | the functions <tt>SWIG_TypeQuery</tt>, <tt>SWIG_NewPointerObj</tt>, and others sometimes need | |
84 | to be called. Calling these functions from a typemap is supported, since the typemap code | |
85 | is embedded into the <tt>_wrap.c</tt> file, which has those declerations available. If you need | |
86 | to call the SWIG run-time functions from another C file, there is one header you need | |
87 | to include. To generate the header that needs to be included, run the following command: | |
88 | ||
89 | <div class="code"><pre> | |
90 | $ swig -python -external-runtime <filename> | |
91 | </pre></div> | |
92 | ||
93 | <p>The filename argument is optional and if it is not passed, then the default filename will | |
94 | be something like <tt>swigpyrun.h</tt>, depending on the language. This header file should | |
95 | be treated like any of the other _wrap.c output files, and should be regenerated when the | |
96 | _wrap files are. After including this header, your code will be able to call <tt>SWIG_TypeQuery</tt>, | |
97 | <tt>SWIG_NewPointerObj</tt>, <tt>SWIG_ConvertPtr</tt> and others. The exact argument paramaters | |
98 | for these functions might differ between language modules; please check the language module chapters | |
99 | for more information.</p> | |
100 | ||
101 | <p>Inside this header the functions are declared static and are included inline into the file, | |
102 | and thus the file does not need to be linked against any SWIG libraries or code (you might still | |
103 | need to link against the language libraries like libpython-2.3). Data is shared between this | |
104 | file and the _wrap.c files through a global variable in the scripting language. It is also | |
105 | possible to copy this header file along with the generated wrapper files into your own package, | |
106 | so that you can distribute a package that can be compiled without SWIG installed (this works | |
107 | because the header file is self contained, and does not need to link with anything).</p> | |
108 | ||
109 | <H2><a name="Modules_nn4"></a>15.3 A word of caution about static libraries</H2> | |
110 | ||
111 | ||
112 | <p> | |
113 | When working with multiple SWIG modules, you should take care not to use static | |
114 | libraries. For example, if you have a static library <tt>libfoo.a</tt> and you link a collection | |
115 | of SWIG modules with that library, each module will get its own private copy of the library code inserted | |
116 | into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program | |
117 | behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libaries. | |
118 | </p> | |
119 | ||
120 | <H2><a name="Modules_nn5"></a>15.4 References</H2> | |
121 | ||
122 | ||
123 | <p> | |
124 | Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult | |
125 | an outside reference. John Levine's "Linkers and Loaders" is highly recommended. | |
126 | </p> | |
127 | ||
128 | <H2><a name="Modules_nn6"></a>15.5 Reducing the wrapper file size</H2> | |
129 | ||
130 | ||
131 | <p> | |
132 | Using multiple modules with the <tt>%import</tt> directive is the most common approach to modularising large projects. | |
133 | In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file. | |
134 | There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options and features. | |
135 | </p> | |
136 | ||
137 | <p> | |
138 | <b>-fcompact</b><br> | |
139 | This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file. | |
140 | It simply removes blank lines and joins lines of code together. | |
141 | This is useful for compilers that have a maximum file size that can be handled. | |
142 | </p> | |
143 | ||
144 | <p> | |
145 | <b>-fvirtual</b><br> | |
146 | This command line option will remove the generation of superfluous virtual method wrappers. | |
147 | Consider the following inheritance hierarchy: | |
148 | </p> | |
149 | ||
150 | <div class="code"> | |
151 | <pre> | |
152 | struct Base { | |
153 | virtual void method(); | |
154 | ... | |
155 | }; | |
156 | ||
157 | struct Derived : Base { | |
158 | virtual void method(); | |
159 | ... | |
160 | }; | |
161 | </pre> | |
162 | </div> | |
163 | ||
164 | <p> | |
165 | Normally wrappers are generated for both methods, whereas this command line option will suppress the generation of a wrapper for <tt>Derived::method</tt>. | |
166 | Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have | |
167 | a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>. | |
168 | </p> | |
169 | ||
170 | <p> | |
171 | <b>%feature("compactdefaultargs")</b><br> | |
172 | 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 it's limitations. | |
173 | </p> | |
174 | ||
175 | </body> | |
176 | </html> |