PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms


HTML | 259 lines | 211 code | 46 blank | 2 comment | 0 complexity | efee333b18121f34a5a8274cb8d8f738 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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. <body bgcolor="#ffffff">
  8. <H1><a name="Modules"></a>15 Working with Modules</H1>
  9. <!-- INDEX -->
  10. <div class="sectiontoc">
  11. <ul>
  12. <li><a href="#Modules_nn1">Basics</a>
  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. <p>
  22. When first working with SWIG, users commonly start by creating a
  23. single module. That is, you might define a single SWIG interface that
  24. wraps some set of C/C++ code. You then compile all of the generated
  25. wrapper code into a module and use it. For large applications, however,
  26. this approach is problematic---the size of the generated wrapper code
  27. can be rather large. Moreover, it is probably easier to manage the
  28. target language interface when it is broken up into smaller pieces.
  29. </p>
  30. <p>
  31. This chapter describes the problem of using SWIG in programs
  32. where you want to create a collection of modules.
  33. </p>
  34. <H2><a name="Modules_nn1"></a>15.1 Basics</H2>
  35. <p>
  36. The basic usage case with multiple modules is when modules do not have
  37. cross-references (ie. when wrapping multiple independent C APIs). In that case,
  38. swig input files should just work out of the box - you simply create multiple
  39. wrapper .cxx files, link them into your application, and insert/load each in the
  40. scripting language runtime as you would do for the single module case.
  41. </p>
  42. <p>
  43. A bit more complex is the case in which modules need to share information.
  44. For example, when one module extends the class of the another by deriving from
  45. it:
  46. </p>
  47. <div class="code"><pre>
  48. %module base
  49. %inline %{
  50. class base {
  51. public:
  52. int foo(void);
  53. };
  54. %}
  55. </pre></div>
  56. &nbsp;
  57. <div class="code"><pre>
  58. %module derived
  59. %import "base.i"
  60. %inline %{
  61. class derived : public base {
  62. public:
  63. int bar(void);
  64. };
  65. %}
  66. </pre></div>
  67. <p>To create the wrapper properly, module <tt>derived</tt> needs to know the
  68. <tt>base</tt> class and that it's interface is covered in another module. The
  69. line <tt>%import "base.i"</tt> lets SWIG know exactly that. The common mistake here is
  70. to <tt>%import</tt> the <tt>.h</tt> file instead of the <tt>.i</tt>, which sadly won't do the trick. Another issue
  71. to take care of is that multiple dependent wrappers should not be linked/loaded
  72. in parallel from multiple threads as SWIG provides no locking - for more on that
  73. issue, read on.</p>
  74. <H2><a name="Modules_nn2"></a>15.2 The SWIG runtime code</H2>
  75. <p>
  76. Many of SWIG's target languages generate a set of functions commonly known as
  77. the "SWIG runtime." These functions are primarily related to the runtime type
  78. system which checks pointer types and performs other tasks such as proper
  79. casting of pointer values in C++. As a general rule, the statically typed target
  80. languages, such as Java, use the language's built in static type checking and
  81. have no need for a SWIG runtime. All the dynamically typed / interpreted
  82. languages rely on the SWIG runtime.
  83. </p>
  84. <p>
  85. The runtime functions are private to each SWIG-generated module. That is, the
  86. runtime functions are declared with "static" linkage and are visible only to the
  87. wrapper functions defined in that module. The only problem with this approach is
  88. that when more than one SWIG module is used in the same application, those
  89. modules often need to share type information. This is especially true for C++
  90. programs where SWIG must collect and share information about inheritance
  91. relationships that cross module boundaries.
  92. </p>
  93. <p>
  94. To solve the problem of sharing information across modules, a pointer to the
  95. type information is stored in a global variable in the target language
  96. namespace. During module initialization, type information is loaded into the
  97. global data structure of type information from all modules.
  98. </p>
  99. <p>
  100. There are a few trade offs with this approach. This type information is global
  101. across all SWIG modules loaded, and can cause type conflicts between modules
  102. that were not designed to work together. To solve this approach, the SWIG
  103. runtime code uses a define SWIG_TYPE_TABLE to provide a unique type table. This
  104. behavior can be enabled when compiling the generated _wrap.cxx or _wrap.c file
  105. by adding -DSWIG_TYPE_TABLE=myprojectname to the command line argument.
  106. </p>
  107. <p>
  108. Then, only modules compiled with SWIG_TYPE_TABLE set to myprojectname will share
  109. type information. So if your project has three modules, all three should be
  110. compiled with -DSWIG_TYPE_TABLE=myprojectname, and then these three modules will
  111. share type information. But any other project's types will not interfere or
  112. clash with the types in your module.
  113. </p>
  114. <p>
  115. Another issue relating to the global type table is thread safety. If two modules
  116. try and load at the same time, the type information can become corrupt. SWIG
  117. currently does not provide any locking, and if you use threads, you must make
  118. sure that modules are loaded serially. Be careful if you use threads and the
  119. automatic module loading that some scripting languages provide. One solution is
  120. to load all modules before spawning any threads, or use SWIG_TYPE_TABLE to
  121. separate type tables so they do not clash with each other.
  122. </p>
  123. <p>
  124. Lastly, SWIG uses a #define SWIG_RUNTIME_VERSION, located in Lib/swigrun.swg and
  125. near the top of every generated module. This number gets incremented when the
  126. data structures change, so that SWIG modules generated with different versions
  127. can peacefully coexist. So the type structures are separated by the
  129. is empty. Only modules compiled with the same pair will share type information.
  130. </p>
  131. <H2><a name="external_run_time"></a>15.3 External access to the runtime</H2>
  132. <p>As described in <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>,
  133. the functions <tt>SWIG_TypeQuery</tt>, <tt>SWIG_NewPointerObj</tt>, and others sometimes need
  134. to be called. Calling these functions from a typemap is supported, since the typemap code
  135. is embedded into the <tt>_wrap.c</tt> file, which has those declarations available. If you need
  136. to call the SWIG run-time functions from another C file, there is one header you need
  137. to include. To generate the header that needs to be included, run the following command:
  138. <div class="shell"><pre>
  139. $ swig -python -external-runtime &lt;filename&gt;
  140. </pre></div>
  141. <p>The filename argument is optional and if it is not passed, then the default filename will
  142. be something like <tt>swigpyrun.h</tt>, depending on the language. This header file should
  143. be treated like any of the other _wrap.c output files, and should be regenerated when the
  144. _wrap files are. After including this header, your code will be able to call <tt>SWIG_TypeQuery</tt>,
  145. <tt>SWIG_NewPointerObj</tt>, <tt>SWIG_ConvertPtr</tt> and others. The exact argument parameters
  146. for these functions might differ between language modules; please check the language module chapters
  147. for more information.</p>
  148. <p>Inside this header the functions are declared static and are included inline into the file,
  149. and thus the file does not need to be linked against any SWIG libraries or code (you might still
  150. need to link against the language libraries like libpython-2.3). Data is shared between this
  151. file and the _wrap.c files through a global variable in the scripting language. It is also
  152. possible to copy this header file along with the generated wrapper files into your own package,
  153. so that you can distribute a package that can be compiled without SWIG installed (this works
  154. because the header file is self-contained, and does not need to link with anything).</p>
  155. <p>
  156. This header will also use the -DSWIG_TYPE_TABLE described above, so when
  157. compiling any code which includes the generated header file should define the
  158. SWIG_TYPE_TABLE to be the same as the module whose types you are trying to
  159. access.
  160. </p>
  161. <H2><a name="Modules_nn4"></a>15.4 A word of caution about static libraries</H2>
  162. <p>
  163. When working with multiple SWIG modules, you should take care not to use static
  164. libraries. For example, if you have a static library <tt>libfoo.a</tt> and you link a collection
  165. of SWIG modules with that library, each module will get its own private copy of the library code inserted
  166. into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program
  167. behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries.
  168. </p>
  169. <H2><a name="Modules_nn5"></a>15.5 References</H2>
  170. <p>
  171. Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult
  172. an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
  173. </p>
  174. <H2><a name="Modules_nn6"></a>15.6 Reducing the wrapper file size</H2>
  175. <p>
  176. Using multiple modules with the <tt>%import</tt> directive is the most common approach to modularising large projects.
  177. In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file.
  178. There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options and features.
  179. </p>
  180. <p>
  181. <b>-fcompact</b><br>
  182. This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file.
  183. It simply removes blank lines and joins lines of code together.
  184. This is useful for compilers that have a maximum file size that can be handled.
  185. </p>
  186. <p>
  187. <b>-fvirtual</b><br>
  188. This command line option will remove the generation of superfluous virtual method wrappers.
  189. Consider the following inheritance hierarchy:
  190. </p>
  191. <div class="code">
  192. <pre>
  193. struct Base {
  194. virtual void method();
  195. ...
  196. };
  197. struct Derived : Base {
  198. virtual void method();
  199. ...
  200. };
  201. </pre>
  202. </div>
  203. <p>
  204. Normally wrappers are generated for both methods, whereas this command line option will suppress the generation of a wrapper for <tt>Derived::method</tt>.
  205. Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have
  206. a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>.
  207. </p>
  208. <p>
  209. <b>%feature("compactdefaultargs")</b><br>
  210. 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.
  211. </p>
  212. </body>
  213. </html>