| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | <!-- Hand-written HTML --> |
| 3 | <html> |
| 4 | <head> |
| 5 | <title>SWIG and Chicken</title> |
| 6 | <link rel="stylesheet" type="text/css" href="style.css"> |
| 7 | </head> |
| 8 | |
| 9 | <body bgcolor="#ffffff"> |
| 10 | |
| 11 | <H1><a name="Chicken"></a>17 SWIG and Chicken</H1> |
| 12 | <!-- INDEX --> |
| 13 | <div class="sectiontoc"> |
| 14 | <ul> |
| 15 | <li><a href="#Chicken_nn2">Preliminaries</a> |
| 16 | <ul> |
| 17 | <li><a href="#Chicken_nn3">Running SWIG in C mode</a> |
| 18 | <li><a href="#Chicken_nn4">Running SWIG in C++ mode</a> |
| 19 | </ul> |
| 20 | <li><a href="#Chicken_nn5">Code Generation</a> |
| 21 | <ul> |
| 22 | <li><a href="#Chicken_nn6">Naming Conventions</a> |
| 23 | <li><a href="#Chicken_nn7">Modules</a> |
| 24 | <li><a href="#Chicken_nn8">Constants and Variables</a> |
| 25 | <li><a href="#Chicken_nn9">Functions</a> |
| 26 | <li><a href="#Chicken_nn10">Exceptions</a> |
| 27 | </ul> |
| 28 | <li><a href="#Chicken_nn11">TinyCLOS</a> |
| 29 | <li><a href="#Chicken_nn12">Linkage</a> |
| 30 | <ul> |
| 31 | <li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a> |
| 32 | <li><a href="#Chicken_nn14">Building chicken extension libraries</a> |
| 33 | <li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a> |
| 34 | </ul> |
| 35 | <li><a href="#Chicken_nn16">Typemaps</a> |
| 36 | <li><a href="#Chicken_nn17">Pointers</a> |
| 37 | <ul> |
| 38 | <li><a href="#collection">Garbage collection</a> |
| 39 | </ul> |
| 40 | <li><a href="#Chicken_nn18">Unsupported features and known problems</a> |
| 41 | </ul> |
| 42 | </div> |
| 43 | <!-- INDEX --> |
| 44 | |
| 45 | |
| 46 | |
| 47 | <p> |
| 48 | This chapter describes SWIG's support of CHICKEN. CHICKEN is a |
| 49 | Scheme-to-C compiler supporting most of the language features as |
| 50 | defined in the <i>Revised^5 Report on Scheme</i>. Its main |
| 51 | attributes are that it |
| 52 | </p> |
| 53 | |
| 54 | <ol> |
| 55 | <li>generates portable C code</li> |
| 56 | <li>includes a customizable interpreter</li> |
| 57 | <li>links to C libraries with a simple Foreign Function Interface</li> |
| 58 | <li>supports full tail-recursion and first-class continuations</li> |
| 59 | </ol> |
| 60 | |
| 61 | <p> |
| 62 | When confronted with a large C library, CHICKEN users can use |
| 63 | SWIG to generate CHICKEN wrappers for the C library. However, |
| 64 | the real advantages of using SWIG with CHICKEN are its |
| 65 | <strong>support for C++</strong> -- object-oriented code is |
| 66 | difficult to wrap by hand in CHICKEN -- and its <strong>typed |
| 67 | pointer representation</strong>, essential for C and C++ |
| 68 | libraries involving structures or classes. |
| 69 | |
| 70 | </p> |
| 71 | |
| 72 | <H2><a name="Chicken_nn2"></a>17.1 Preliminaries</H2> |
| 73 | |
| 74 | |
| 75 | <p> |
| 76 | CHICKEN support was introduced to SWIG in version 1.3.18. SWIG |
| 77 | relies on some recent additions to CHICKEN, which are only |
| 78 | present in releases of CHICKEN with version number |
| 79 | <strong>greater than or equal to 1.89</strong>. |
| 80 | To use a chicken version between 1.40 and 1.89, see the <a href="#collection">Garbage collection</a> |
| 81 | section below. |
| 82 | </p> |
| 83 | |
| 84 | <p> |
| 85 | You may want to look at any of the examples in Examples/chicken/ |
| 86 | or Examples/GIFPlot/Chicken for the basic steps to run SWIG |
| 87 | CHICKEN. |
| 88 | </p> |
| 89 | |
| 90 | <H3><a name="Chicken_nn3"></a>17.1.1 Running SWIG in C mode</H3> |
| 91 | |
| 92 | |
| 93 | <p> |
| 94 | To run SWIG CHICKEN in C mode, use |
| 95 | the -chicken option. |
| 96 | </p> |
| 97 | |
| 98 | <div class="shell"> |
| 99 | <pre>% swig -chicken example.i</pre> |
| 100 | </div> |
| 101 | |
| 102 | <p> |
| 103 | To allow the wrapper to take advantage of future CHICKEN code |
| 104 | generation improvements, part of the wrapper is direct CHICKEN |
| 105 | function calls (<tt>example_wrap.c</tt>) and part is CHICKEN |
| 106 | Scheme (<tt>example.scm</tt>). The basic Scheme code must |
| 107 | be compiled to C using your system's CHICKEN compiler or |
| 108 | both files can be compiled directly using the much simpler <tt>csc</tt>. |
| 109 | </p> |
| 110 | |
| 111 | <div class="shell"> |
| 112 | <pre> |
| 113 | % chicken example.scm -output-file oexample.c |
| 114 | </pre> |
| 115 | </div> |
| 116 | |
| 117 | <p> |
| 118 | So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and |
| 119 | <tt>oexample.c</tt> are the files that must be compiled to |
| 120 | object files and linked into your project. |
| 121 | </p> |
| 122 | |
| 123 | <H3><a name="Chicken_nn4"></a>17.1.2 Running SWIG in C++ mode</H3> |
| 124 | |
| 125 | |
| 126 | <p> |
| 127 | To run SWIG CHICKEN in C++ mode, use |
| 128 | the -chicken -c++ option. |
| 129 | </p> |
| 130 | |
| 131 | <div class="shell"> |
| 132 | <pre>% swig -chicken -c++ example.i</pre> |
| 133 | </div> |
| 134 | |
| 135 | <p> |
| 136 | This will generate <tt>example_wrap.cxx</tt> and |
| 137 | <tt>example.scm</tt>. The basic Scheme code must be |
| 138 | compiled to C using your system's CHICKEN compiler or |
| 139 | both files can be compiled directly using the much simpler <tt>csc</tt>. |
| 140 | </p> |
| 141 | |
| 142 | <div class="shell"> |
| 143 | <pre>% chicken example.scm -output-file oexample.c</pre> |
| 144 | </div> |
| 145 | |
| 146 | <p> |
| 147 | So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt> |
| 148 | and <tt>oexample.c</tt> are the files that must be compiled to |
| 149 | object files and linked into your project. |
| 150 | </p> |
| 151 | |
| 152 | <H2><a name="Chicken_nn5"></a>17.2 Code Generation</H2> |
| 153 | |
| 154 | |
| 155 | <H3><a name="Chicken_nn6"></a>17.2.1 Naming Conventions</H3> |
| 156 | |
| 157 | |
| 158 | <p> |
| 159 | Given a C variable, function or constant declaration named |
| 160 | <tt>Foo_Bar</tt>, the declaration will be available |
| 161 | in CHICKEN as an identifier ending with |
| 162 | <tt>Foo-Bar</tt>. That is, an underscore is converted |
| 163 | to a dash. |
| 164 | </p> |
| 165 | |
| 166 | <p> |
| 167 | You may control what the CHICKEN identifier will be by using the |
| 168 | <tt>%rename</tt> SWIG directive in the SWIG interface file. |
| 169 | </p> |
| 170 | |
| 171 | <H3><a name="Chicken_nn7"></a>17.2.2 Modules</H3> |
| 172 | |
| 173 | |
| 174 | <p> |
| 175 | The name of the module must be declared one of two ways: |
| 176 | <ul> |
| 177 | <li>Placing <tt>%module example</tt> in the SWIG interface |
| 178 | file.</li> |
| 179 | <li>Using <tt>-module example</tt> on the SWIG command |
| 180 | line.</li> |
| 181 | </ul> |
| 182 | |
| 183 | <p> |
| 184 | The generated example.scm file then exports <code>(declare (unit modulename))</code>. |
| 185 | If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass |
| 186 | the -nounit option to SWIG. |
| 187 | |
| 188 | <p> |
| 189 | CHICKEN will be able to access the module using the <code>(declare |
| 190 | (uses <i>modulename</i>))</code> CHICKEN Scheme form. |
| 191 | </p> |
| 192 | |
| 193 | <H3><a name="Chicken_nn8"></a>17.2.3 Constants and Variables</H3> |
| 194 | |
| 195 | |
| 196 | <p> |
| 197 | Constants may be created using any of the four constructs in |
| 198 | the interface file: |
| 199 | </p> |
| 200 | <ol> |
| 201 | <li><code>#define MYCONSTANT1 ...</code></li> |
| 202 | <li><code>%constant int MYCONSTANT2 = ...</code></li> |
| 203 | <li><code>const int MYCONSTANT3 = ...</code></li> |
| 204 | <li><code>enum { MYCONSTANT4 = ... };</code></li> |
| 205 | </ol> |
| 206 | |
| 207 | <p> |
| 208 | In all cases, the constants may be accessed from within CHICKEN |
| 209 | using the form <tt>(MYCONSTANT1)</tt>; that is, the constants |
| 210 | may be accessed using the read-only parameter form. |
| 211 | </p> |
| 212 | |
| 213 | <p> |
| 214 | Variables are accessed using the full parameter form. |
| 215 | For example, to set the C variable "int my_variable;", use the |
| 216 | Scheme form <tt>(my-variable 2345)</tt>. To get the C variable, |
| 217 | use <tt>(my-variable)</tt>. |
| 218 | </p> |
| 219 | |
| 220 | <H3><a name="Chicken_nn9"></a>17.2.4 Functions</H3> |
| 221 | |
| 222 | |
| 223 | <p> |
| 224 | C functions declared in the SWIG interface file will have |
| 225 | corresponding CHICKEN Scheme procedures. For example, the C |
| 226 | function "int sqrt(double x);" will be available using the |
| 227 | Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return |
| 228 | value will give C_SCHEME_UNDEFINED as a result. |
| 229 | </p> |
| 230 | <p> |
| 231 | A function may return more than one value by using the |
| 232 | <code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i). |
| 233 | They will be returned as multiple values using <code>(values)</code> if there is more than one |
| 234 | result (that is, a non-void return value and at least one argout |
| 235 | parameter, or a void return value and at least two argout |
| 236 | parameters). The return values can then be accessed with <code>(call-with-values)</code>. |
| 237 | </p> |
| 238 | |
| 239 | <H3><a name="Chicken_nn10"></a>17.2.5 Exceptions</H3> |
| 240 | |
| 241 | |
| 242 | <p>The SWIG chicken module has support for exceptions thrown from |
| 243 | C or C++ code to be caught in scheme. |
| 244 | See <a href="Customization.html#exception">Exception handling with %exception</a> |
| 245 | for more information about declaring exceptions in the interface file. |
| 246 | </p> |
| 247 | |
| 248 | <p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface |
| 249 | as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from |
| 250 | inside the %exception blocks. <code>SWIG_exception</code> will throw a list consisting of the code |
| 251 | (as an integer) and the message. Both of these will throw an exception using <code>(abort)</code>, |
| 252 | which can be handled by <code>(handle-exceptions)</code>. See |
| 253 | <a href="http://www.call-with-current-continuation.org/manual/Exceptions.html#Exceptions">Chicken manual on Exceptions</a> |
| 254 | and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>. Since the exception values are thrown |
| 255 | directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case. |
| 256 | </p> |
| 257 | |
| 258 | <p>The following simple module</p> |
| 259 | |
| 260 | <div class="code"><pre> |
| 261 | %module exception_test |
| 262 | |
| 263 | %inline %{ |
| 264 | void test_throw(int i) throws (int) { |
| 265 | if (i == 1) throw 15; |
| 266 | } |
| 267 | %} |
| 268 | </pre></div> |
| 269 | |
| 270 | <p>could be run with</p> |
| 271 | |
| 272 | <div class="targetlang"><pre> |
| 273 | (handle-exceptions exvar |
| 274 | (if (= exvar 15) |
| 275 | (print "Correct!") |
| 276 | (print "Threw something else " exvar)) |
| 277 | (test-throw 1)) |
| 278 | </pre></div> |
| 279 | |
| 280 | |
| 281 | <H2><a name="Chicken_nn11"></a>17.3 TinyCLOS</H2> |
| 282 | |
| 283 | |
| 284 | <p> |
| 285 | The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as: |
| 286 | "Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a |
| 287 | metaobject protocol. The implementation is even simpler than |
| 288 | the simple CLOS found in `The Art of the Metaobject Protocol,' |
| 289 | weighing in at around 850 lines of code, including (some) |
| 290 | comments and documentation." |
| 291 | </p> |
| 292 | |
| 293 | <p> |
| 294 | Almost all good Scheme books describe how to use metaobjects and |
| 295 | generic procedures to implement an object-oriented Scheme |
| 296 | system. Please consult a Scheme book if you are unfamiliar |
| 297 | with the concept. |
| 298 | </p> |
| 299 | |
| 300 | <p> |
| 301 | |
| 302 | CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN |
| 303 | uses if the -proxy argument is given. If -proxy is passed, then |
| 304 | the generated example.scm file will contain TinyCLOS class definitions. |
| 305 | A class named Foo is declared as <Foo>, and each member variable |
| 306 | is allocated a slot. Member functions are exported as generic functions. |
| 307 | |
| 308 | <p> |
| 309 | |
| 310 | Primitive symbols and functions (the interface that would be presented if |
| 311 | -proxy was not passed) are hidden and no longer accessable. If the -unhideprimitive |
| 312 | command line argument is passed to SWIG, then the primitive symbols will be |
| 313 | available, but each will be prefixed by the string "primitive:" |
| 314 | |
| 315 | <p> |
| 316 | |
| 317 | The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments. |
| 318 | If -useclassprefix is passed to SWIG, every member function will be generated with the class name |
| 319 | as a prefix. If the -closprefix mymod: argument is passed to SWIG, then the exported functions will |
| 320 | be prefixed by the string "mymod:". If -useclassprefix is passed, -closprefix is ignored. |
| 321 | |
| 322 | </p> |
| 323 | |
| 324 | <H2><a name="Chicken_nn12"></a>17.4 Linkage</H2> |
| 325 | |
| 326 | |
| 327 | <p> |
| 328 | Please refer to <em>CHICKEN - A practical and portable Scheme |
| 329 | system - User's manual</em> for detailed help on how to link |
| 330 | object files to create a CHICKEN Scheme program. Briefly, to |
| 331 | link object files, be sure to add <tt>`chicken-config |
| 332 | -extra-libs -libs`</tt> or <tt>`chicken-config -shared |
| 333 | -extra-libs -libs`</tt>to your linker options. Use the |
| 334 | <tt>-shared</tt> option if you want to create a dynamically |
| 335 | loadable module. You might also want to use the much simpler |
| 336 | <tt>csc</tt> or <tt>csc.bat</tt>. |
| 337 | </p> |
| 338 | |
| 339 | <p>Each scheme file that is generated |
| 340 | by SWIG contains <code>(declare (uses <i>modname</i>))</code>. This means that to load the |
| 341 | module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>. |
| 342 | </p> |
| 343 | |
| 344 | |
| 345 | <H3><a name="Chicken_nn13"></a>17.4.1 Static binary or shared library linked at compile time</H3> |
| 346 | |
| 347 | |
| 348 | <p>We can easily use csc to build a static binary.</p> |
| 349 | |
| 350 | <div class="shell"> |
| 351 | <pre> |
| 352 | $ swig -chicken example.i |
| 353 | $ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example |
| 354 | $ ./example |
| 355 | </pre> |
| 356 | </div> |
| 357 | |
| 358 | <p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled |
| 359 | into a shared library, and then that shared library linked when compiling the |
| 360 | main application.</p> |
| 361 | |
| 362 | <div class="shell"> |
| 363 | <pre> |
| 364 | $ swig -chicken example.i |
| 365 | $ csc -sv example.scm example_wrap.c example_impl.c -o example.so |
| 366 | </pre> |
| 367 | </div> |
| 368 | |
| 369 | <p>The <tt>exmaple.so</tt> file can then linked with <tt>test_script.scm</tt> when it |
| 370 | is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>. |
| 371 | Multiple SWIG modules could have been linked into <tt>example.so</tt> and each |
| 372 | one accessed with a <code>(declare (uses ... ))</code>. |
| 373 | </p> |
| 374 | |
| 375 | <div class="shell"> |
| 376 | <pre> |
| 377 | $ csc -v test_script.scm -lexample |
| 378 | </pre> |
| 379 | </div> |
| 380 | |
| 381 | <p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>, |
| 382 | in which case the test script does not need to be linked with example.so. The test_script.scm file can then |
| 383 | be run with <tt>csi</tt>. |
| 384 | </p> |
| 385 | |
| 386 | <H3><a name="Chicken_nn14"></a>17.4.2 Building chicken extension libraries</H3> |
| 387 | |
| 388 | |
| 389 | <p>Building a shared library like in the above section only works if the library |
| 390 | is linked at compile time with a script containing <code>(declare (uses ...))</code> or is |
| 391 | loaded explicitly with <code>(load-library 'example "example.so")</code>. It is |
| 392 | not the format that CHICKEN expects for extension libraries and eggs. The problem is the |
| 393 | <code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file. There are |
| 394 | two possible solutions to this.</p> |
| 395 | |
| 396 | <p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code> |
| 397 | is not generated. Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into |
| 398 | their own shared library.</p> |
| 399 | |
| 400 | <div class="shell"> |
| 401 | <pre> |
| 402 | $ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so |
| 403 | </pre> |
| 404 | </div> |
| 405 | |
| 406 | <p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function. |
| 407 | See <a href="http://www.call-with-current-continuation.org/manual/Loading-extension-libraries.html"> |
| 408 | Loading-extension-libraries</a> in the eval unit inside the CHICKEN manual for more information.</p> |
| 409 | |
| 410 | <p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code> |
| 411 | and then compile that file into the shared library as well. For example, inside the <tt>mod_load.scm</tt> file,</p> |
| 412 | |
| 413 | <div class="targetlang"> |
| 414 | <pre> |
| 415 | (declare (uses mod1)) |
| 416 | (declare (uses mod2)) |
| 417 | </pre> |
| 418 | </div> |
| 419 | |
| 420 | <p>Which would then be compiled with</p> |
| 421 | |
| 422 | <div class="shell"> |
| 423 | <pre> |
| 424 | $ swig -chicken mod1.i |
| 425 | $ swig -chicken mod2.i |
| 426 | $ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so |
| 427 | </pre> |
| 428 | </div> |
| 429 | |
| 430 | <p>Then the extension library can be loaded with <code>(require 'mod)</code>. As we can see here, |
| 431 | <tt>mod_load.scm</tt> contains the code that gets exectued when the module is loaded. All this code |
| 432 | does is load both mod1 and mod2. As we can see, this technique is more useful when you want to |
| 433 | combine a few SWIG modules into one chicken extension library, especially if modules are related by |
| 434 | <code>%import</code></p> |
| 435 | |
| 436 | <p>In either method, the files that are compiled into the shared library could also be |
| 437 | packaged into an egg. The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG |
| 438 | are stand alone and do not need SWIG to be installed to be compiled. Thus the egg could be |
| 439 | distributed and used by anyone, even if SWIG is not installed.</p> |
| 440 | |
| 441 | <p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds |
| 442 | two eggs, one using the first method and one using the second method.</p> |
| 443 | |
| 444 | <H3><a name="Chicken_nn15"></a>17.4.3 Linking multiple SWIG modules with TinyCLOS</H3> |
| 445 | |
| 446 | |
| 447 | <p>Linking together multiple modules that share type information using the <code>%import</code> |
| 448 | directive while also using <tt>-proxy</tt> is more complicated. For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the |
| 449 | <tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>, |
| 450 | and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported |
| 451 | to the top of <tt>mod2.scm</tt>. By default, when SWIG encounters an <code>%import "modname.i"</code> directive, |
| 452 | it exports <code>(declare (uses <i>modname</i>))</code> into the scm file. This works fine unless mod1 was compiled with |
| 453 | the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p> |
| 454 | |
| 455 | <p>One option is to override the automatic generation of <code>(declare (uses mod1))</code> |
| 456 | by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>. |
| 457 | SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive. Any scheme code inside that directive is inserted into the |
| 458 | generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>. |
| 459 | This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code> |
| 460 | (which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p> |
| 461 | |
| 462 | <p>The other option is to use the second idea in the above section. Compile all the modules normally, without any |
| 463 | <code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>. Then the modules will import each other correctly |
| 464 | with <code>(declare (uses ...))</code>. |
| 465 | To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code> |
| 466 | all the modules.</p> |
| 467 | |
| 468 | <H2><a name="Chicken_nn16"></a>17.5 Typemaps</H2> |
| 469 | |
| 470 | |
| 471 | <p> |
| 472 | The Chicken module handles all types via typemaps. This information is |
| 473 | read from <code>Lib/chicken/typemaps.i</code> and |
| 474 | <code>Lib/chicken/chicken.swg</code>. |
| 475 | </p> |
| 476 | |
| 477 | <H2><a name="Chicken_nn17"></a>17.6 Pointers</H2> |
| 478 | |
| 479 | |
| 480 | <p> |
| 481 | For pointer types, SWIG uses CHICKEN tagged pointers. |
| 482 | |
| 483 | A tagged pointer is an ordinary CHICKEN pointer with an |
| 484 | extra slot for a void *. With SWIG |
| 485 | CHICKEN, this void * is a pointer to a type-info |
| 486 | structure. So each pointer used as input or output from |
| 487 | the SWIG-generated CHICKEN wrappers will have type |
| 488 | information attached to it. This will let the wrappers |
| 489 | correctly determine which method should be called |
| 490 | according to the object type hierarchy exposed in the SWIG |
| 491 | interface files. |
| 492 | </p> |
| 493 | <p> |
| 494 | To construct a Scheme object from a C pointer, the wrapper code |
| 495 | calls the function |
| 496 | <code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>, |
| 497 | The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared |
| 498 | <code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code> |
| 499 | It is ok to call <code>SWIG_NewPointerObj</code> more than once, |
| 500 | just make sure known_space has enough space for all the created pointers. |
| 501 | </p> |
| 502 | <p> |
| 503 | To get the pointer represented by a CHICKEN tagged pointer, the |
| 504 | wrapper code calls the function |
| 505 | <code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>, |
| 506 | passing a pointer to a struct representing the expected pointer |
| 507 | type. flags is either zero or SWIG_POINTER_DISOWN (see below). |
| 508 | </p> |
| 509 | |
| 510 | <H3><a name="collection"></a>17.6.1 Garbage collection</H3> |
| 511 | |
| 512 | |
| 513 | <p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a |
| 514 | finalizer to the type which will call the destructor or delete method of |
| 515 | that type. The destructor and delete functions are no longer exported for |
| 516 | use in scheme code, instead SWIG and chicken manage pointers. |
| 517 | In situations where SWIG knows that a function is returning a type that should |
| 518 | be garbage collected, SWIG will automaticly set the owner flag to 1. For other functions, |
| 519 | the <code>%newobject</code> directive must be specified for functions whose return values |
| 520 | should be garbage collected. See |
| 521 | <a href="Customization.html#ownership">Object ownership and %newobject</a> for more information. |
| 522 | </p> |
| 523 | |
| 524 | <p>In situations where a C or C++ function will assume ownership of a pointer, and thus |
| 525 | chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap. |
| 526 | After applying this typemap (see the <a href="Typemaps.html">Typemaps chapter</a> for more information on how to apply typemaps), |
| 527 | any pointer that gets passed in will no longer be garbage collected. |
| 528 | An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>. |
| 529 | <b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might |
| 530 | get deleted while the scheme code still holds a pointer to it. Further use of this pointer |
| 531 | can lead to a crash. |
| 532 | </p> |
| 533 | |
| 534 | <p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection |
| 535 | does not work for chicken versions below 1.89. If you would like the SWIG generated code to work with |
| 536 | chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG. This will not export code |
| 537 | inside the _wrap.c file to register finalizers, and will then export destructor functions which |
| 538 | must be called manually. |
| 539 | </p> |
| 540 | |
| 541 | <H2><a name="Chicken_nn18"></a>17.7 Unsupported features and known problems</H2> |
| 542 | |
| 543 | |
| 544 | <ul> |
| 545 | <li>No director support.</li> |
| 546 | <li>No support for c++ standard types like std::vector.</li> |
| 547 | <li>The TinyCLOS wrappers for overloaded functions will not work correctly when using |
| 548 | <a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li> |
| 549 | </ul> |
| 550 | |
| 551 | <p>TinyCLOS has a limitation such that generic methods do not properly work on methods |
| 552 | with different number of specializers: TinyCLOS assumes that every method added to a generic function |
| 553 | will have the same number of specializers. SWIG generates functions with different lengths of specializers |
| 554 | when C/C++ functions are overloaded. For example, the code</p> |
| 555 | |
| 556 | <div class="code"> |
| 557 | <pre> |
| 558 | class Foo {}; |
| 559 | int foo(int a, Foo *b); |
| 560 | int foo(int a); |
| 561 | </pre></div> |
| 562 | |
| 563 | <p>will produce scheme code</p> |
| 564 | |
| 565 | <div class="targetlang"> |
| 566 | <pre> |
| 567 | (define-method (foo (arg0 <top>) (arg1 <Foo>)) (<i>call primitive function</i>)) |
| 568 | (define-method (foo (arg0 <top>)) (<i>call primitive function</i>)) |
| 569 | </pre></div> |
| 570 | |
| 571 | <p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one, |
| 572 | so calling <code>(foo 3 f)</code> will produce an error.</p> |
| 573 | |
| 574 | <p>There are two solutions to this: the |
| 575 | file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against |
| 576 | tinyclos.scm inside the chicken source to add support into TinyCLOS for multi-argument generics. |
| 577 | This requires chicken to be rebuilt and custom install of chicken. An alternative is the <tt>Lib/chicken/multi-generic.scm</tt> |
| 578 | file in the SWIG source. This file can be loaded after TinyCLOS is loaded, and it will override some functions |
| 579 | inside TinyCLOS to correctly support multi-argument generics. This solution will work on any install of chicken. |
| 580 | Please see the comments at the top of both files for more information.</p> |
| 581 | |
| 582 | </body> |
| 583 | </html> |