| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <title>SWIG and Ocaml</title> |
| 5 | <link rel="stylesheet" type="text/css" href="style.css"> |
| 6 | </head> |
| 7 | <body bgcolor="#ffffff"> |
| 8 | <a name="n1"></a> |
| 9 | <H1><a name="Ocaml"></a>22 SWIG and Ocaml</H1> |
| 10 | <!-- INDEX --> |
| 11 | <div class="sectiontoc"> |
| 12 | <ul> |
| 13 | <li><a href="#Ocaml_nn2">Preliminaries</a> |
| 14 | <ul> |
| 15 | <li><a href="#Ocaml_nn3">Running SWIG</a> |
| 16 | <li><a href="#Ocaml_nn4">Compiling the code</a> |
| 17 | <li><a href="#Ocaml_nn5">The camlp4 module</a> |
| 18 | <li><a href="#Ocaml_nn6">Using your module</a> |
| 19 | <li><a href="#Ocaml_nn7">Compilation problems and compiling with C++</a> |
| 20 | </ul> |
| 21 | <li><a href="#Ocaml_nn8">The low-level Ocaml/C interface</a> |
| 22 | <ul> |
| 23 | <li><a href="#Ocaml_nn9">The generated module</a> |
| 24 | <li><a href="#Ocaml_nn10">Enums</a> |
| 25 | <ul> |
| 26 | <li><a href="#Ocaml_nn11">Enum typing in Ocaml</a> |
| 27 | </ul> |
| 28 | <li><a href="#Ocaml_nn12">Arrays</a> |
| 29 | <ul> |
| 30 | <li><a href="#Ocaml_nn13">Simple types of bounded arrays</a> |
| 31 | <li><a href="#Ocaml_nn14">Complex and unbounded arrays</a> |
| 32 | <li><a href="#Ocaml_nn15">Using an object</a> |
| 33 | <li><a href="#Ocaml_nn16">Example typemap for a function taking float * and int</a> |
| 34 | </ul> |
| 35 | <li><a href="#Ocaml_nn17">C++ Classes</a> |
| 36 | <ul> |
| 37 | <li><a href="#Ocaml_nn18">STL vector and string Example</a> |
| 38 | <li><a href="#Ocaml_nn19">C++ Class Example</a> |
| 39 | <li><a href="#Ocaml_nn20">Compiling the example</a> |
| 40 | <li><a href="#Ocaml_nn21">Sample Session</a> |
| 41 | </ul> |
| 42 | <li><a href="#Ocaml_nn22">Director Classes</a> |
| 43 | <ul> |
| 44 | <li><a href="#Ocaml_nn23">Director Introduction</a> |
| 45 | <li><a href="#Ocaml_nn24">Overriding Methods in Ocaml</a> |
| 46 | <li><a href="#Ocaml_nn25">Director Usage Example</a> |
| 47 | <li><a href="#Ocaml_nn26">Creating director objects</a> |
| 48 | <li><a href="#Ocaml_nn27">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a> |
| 49 | <li><a href="#Ocaml_nn28"><tt>directorin</tt> typemap</a> |
| 50 | <li><a href="#Ocaml_nn29"><tt>directorout</tt> typemap</a> |
| 51 | <li><a href="#Ocaml_nn30"><tt>directorargout</tt> typemap</a> |
| 52 | </ul> |
| 53 | <li><a href="#Ocaml_nn31">Exceptions</a> |
| 54 | </ul> |
| 55 | </ul> |
| 56 | </div> |
| 57 | <!-- INDEX --> |
| 58 | |
| 59 | |
| 60 | |
| 61 | <p> |
| 62 | This chapter describes SWIG's |
| 63 | support of Ocaml. Ocaml is a relatively recent addition to the ML family, |
| 64 | and is a recent addition to SWIG. It's the second compiled, typed |
| 65 | language to be added. Ocaml has widely acknowledged benefits for engineers, |
| 66 | mostly derived from a sophistocated type system, compile-time checking |
| 67 | which eliminates several classes of common programming errors, and good |
| 68 | native performance. While all of this is wonderful, there are well-written |
| 69 | C and C++ libraries that Ocaml users will want to take advantage of as |
| 70 | part of their arsenal (such as SSL and gdbm), as well as their own mature |
| 71 | C and C++ code. SWIG allows this code to be used in a natural, type-safe |
| 72 | way with Ocaml, by providing the necessary, but repetetive glue code |
| 73 | which creates and uses Ocaml values to communicate with C and C++ code. |
| 74 | In addition, SWIG also produces the needed Ocaml source that binds |
| 75 | variants, functions, classes, etc. |
| 76 | </p> |
| 77 | |
| 78 | <p> |
| 79 | If you're not familiar with the Objective Caml language, you can visit |
| 80 | <a href="http://www.ocaml.org/">The Ocaml Website</a>. |
| 81 | </p> |
| 82 | |
| 83 | <H2><a name="Ocaml_nn2"></a>22.1 Preliminaries</H2> |
| 84 | |
| 85 | |
| 86 | <p> |
| 87 | SWIG 1.3 works with Ocaml 3.04 and above. Given the choice, |
| 88 | you should use the latest stable release. The SWIG Ocaml module has |
| 89 | been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The |
| 90 | best way to determine whether your system will work is to compile the |
| 91 | examples and test-suite which come with SWIG. You can do this by running |
| 92 | <tt>make check</tt> from the SWIG root directory after installing SWIG. |
| 93 | The Ocaml module has been tested using the system's dynamic linking (the |
| 94 | usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's |
| 95 | <a |
| 96 | href="http://www.ocaml-programming.de/packages/documentation/dl/">Dl package |
| 97 | </a>. The ocaml_dynamic and ocaml_dynamic_cpp targets in the |
| 98 | file Examples/Makefile illustrate how to compile and link SWIG modules that |
| 99 | will be loaded dynamically. This has only been tested on Linux so far. |
| 100 | </p> |
| 101 | |
| 102 | <H3><a name="Ocaml_nn3"></a>22.1.1 Running SWIG</H3> |
| 103 | |
| 104 | |
| 105 | <p> |
| 106 | The basics of getting a SWIG Ocaml module up and running |
| 107 | can be seen from one of SWIG's example Makefiles, but is also described |
| 108 | here. To build an Ocaml module, run SWIG using the <tt>-ocaml</tt> |
| 109 | option. |
| 110 | </p> |
| 111 | |
| 112 | <div class="code"> |
| 113 | <pre> |
| 114 | %swig -ocaml example.i |
| 115 | </pre> |
| 116 | </div> |
| 117 | |
| 118 | <p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains |
| 119 | all of the C code needed to build an Ocaml module. To build the module, |
| 120 | you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or |
| 121 | <tt>ocamlopt</tt> to create the needed .o file. You will need to compile |
| 122 | the resulting .ml and .mli files as well, and do the final link with -custom |
| 123 | (not needed for native link). </p> |
| 124 | |
| 125 | <H3><a name="Ocaml_nn4"></a>22.1.2 Compiling the code</H3> |
| 126 | |
| 127 | |
| 128 | <p> |
| 129 | The O'Caml SWIG module now requires you to compile a module (<tt>Swig</tt>) |
| 130 | separately. In addition to aggregating common SWIG functionality, the Swig |
| 131 | module contains the data structure that represents C/C++ values. This allows |
| 132 | easier data sharing between modules if two or more are combined, because |
| 133 | the type of each SWIG'ed module's c_obj is derived from Swig.c_obj_t. This |
| 134 | also allows SWIG to acquire new conversions painlessly, as well as giving |
| 135 | the user more freedom with respect to custom typing. |
| 136 | |
| 137 | Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your |
| 138 | SWIG interface like: |
| 139 | </p> |
| 140 | |
| 141 | <div class="code"> |
| 142 | <pre> |
| 143 | % swig -ocaml -co swig.mli ; swig -ocaml co swig.ml |
| 144 | % ocamlc -c swig.mli ; ocamlc -c swig.ml |
| 145 | % ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c |
| 146 | % ocamlc -c example.mli |
| 147 | % ocamlc -c example.ml |
| 148 | </pre> |
| 149 | </div> |
| 150 | |
| 151 | <p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately, |
| 152 | it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked |
| 153 | in C++ mode, you must: </p> |
| 154 | |
| 155 | <div class="code"> |
| 156 | <pre> |
| 157 | % cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br> |
| 158 | </pre> |
| 159 | </div> |
| 160 | |
| 161 | <H3><a name="Ocaml_nn5"></a>22.1.3 The camlp4 module</H3> |
| 162 | |
| 163 | |
| 164 | <p> |
| 165 | The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple rewriter which |
| 166 | makes C++ code blend more seamlessly with objective caml code. It's use is |
| 167 | optional, but encouraged. The source file is included in the Lib/ocaml |
| 168 | directory of the SWIG source distribution. You can checkout this file with |
| 169 | <tt>"swig -ocaml -co swigp4.ml"</tt>. You should compile the file with |
| 170 | <tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt> |
| 171 | </p> |
| 172 | |
| 173 | <p> |
| 174 | The basic principle of the module is to recognize certain non-caml expressions |
| 175 | and convert them for use with C++ code as interfaced by SWIG. The camlp4 |
| 176 | module is written to work with generated SWIG interfaces, and probably isn't |
| 177 | great to use with anything else. |
| 178 | </p> |
| 179 | |
| 180 | <p> |
| 181 | Here are the main rewriting rules: |
| 182 | </p> |
| 183 | |
| 184 | <table border="1" summary="Rewriting rules"> |
| 185 | <tr><th>Input</th><th>Rewritten to</th></tr> |
| 186 | <tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td> |
| 187 | <td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr> |
| 188 | <tr><td>object -> method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr> |
| 189 | <tr><td> |
| 190 | object <i>'binop</i> argument as in<br> |
| 191 | a '+= b</td> |
| 192 | <td> |
| 193 | (invoke object) "+=" argument as in<br> |
| 194 | (invoke a) "+=" b<td></tr> |
| 195 | <tr><th colspan=2>Note that because camlp4 always recognizes << |
| 196 | and >>, they are replaced by lsl and lsr in operator names. |
| 197 | <tr><td> |
| 198 | <i>'unop</i> object as in<br> |
| 199 | '! a |
| 200 | </td><td> |
| 201 | (invoke a) "!" C_void</td></tr> |
| 202 | <tr><td> |
| 203 | <b>Smart pointer access like this</b><br> |
| 204 | object '-> method ( args )<br> |
| 205 | </td><td> |
| 206 | (invoke (invoke object "->" C_void)) |
| 207 | </td></tr> |
| 208 | <tr><td> |
| 209 | <b>Invoke syntax</b><br> |
| 210 | object . '( ... ) |
| 211 | </td><td> |
| 212 | (invoke object) "()" (C_list [ ... ]) |
| 213 | </td></tr> |
| 214 | <tr><td> |
| 215 | <b>Array syntax</b><br> |
| 216 | object '[ 10 ] |
| 217 | </td><td> |
| 218 | (invoke object) "[]" (C_int 10) |
| 219 | </td></tr> |
| 220 | <tr><td> |
| 221 | <b>Assignment syntax</b><br> |
| 222 | let a = '10 and b = '"foo" and c = '1.0 and d = 'true |
| 223 | </td><td> |
| 224 | let a = C_int 10 and b = C_string "foo" and c = C_double 1.0 and d = C_bool true |
| 225 | </td></tr> |
| 226 | <tr><td> |
| 227 | <b>Cast syntax</b><br> |
| 228 | let a = _atoi '("2") as int<br> |
| 229 | let b = (getenv "PATH") to string<br> |
| 230 | This works for int, string, float, bool |
| 231 | </td><td> |
| 232 | let a = get_int (_atoi (C_string "2"))<br> |
| 233 | let b = C_string (getenv "PATH") |
| 234 | </td></tr> |
| 235 | </table> |
| 236 | |
| 237 | <H3><a name="Ocaml_nn6"></a>22.1.4 Using your module</H3> |
| 238 | |
| 239 | |
| 240 | <p> |
| 241 | You can test-drive your module by building a |
| 242 | toplevel ocaml interpreter. Consult the ocaml manual for details. |
| 243 | </p> |
| 244 | |
| 245 | <p> |
| 246 | When linking any ocaml bytecode with your module, use the -custom |
| 247 | option to build your functions into the primitive list. This |
| 248 | option is not needed when you build native code. |
| 249 | </p> |
| 250 | |
| 251 | <H3><a name="Ocaml_nn7"></a>22.1.5 Compilation problems and compiling with C++</H3> |
| 252 | |
| 253 | |
| 254 | <p> |
| 255 | As mentioned above, .cxx files need special |
| 256 | handling to be compiled with <tt>ocamlc</tt>. Other than that, C code |
| 257 | that uses <tt>class</tt> as a non-keyword, and C code that is too |
| 258 | liberal with pointer types may not compile under the C++ compiler. |
| 259 | Most code meant to be compiled as C++ will not have problems. |
| 260 | </p> |
| 261 | |
| 262 | <H2><a name="Ocaml_nn8"></a>22.2 The low-level Ocaml/C interface</H2> |
| 263 | |
| 264 | |
| 265 | <p> |
| 266 | In order to provide access to overloaded functions, and |
| 267 | provide sensible outputs from them, all C entites are represented as |
| 268 | members of the c_obj type: |
| 269 | </p> |
| 270 | |
| 271 | <p> |
| 272 | In the code as seen by the typemap |
| 273 | writer, there is a value, swig_result, that always contains the |
| 274 | current return data. It is a list, and must be appended with the |
| 275 | caml_list_append function, or with functions and macros provided by |
| 276 | objective caml.<br> |
| 277 | </p> |
| 278 | |
| 279 | <div class="code"><pre> |
| 280 | type c_obj = |
| 281 | C_void |
| 282 | | C_bool of bool |
| 283 | | C_char of char |
| 284 | | C_uchar of char |
| 285 | | C_short of int |
| 286 | | C_ushort of int |
| 287 | | C_int of int |
| 288 | | C_uint of int32 |
| 289 | | C_int32 of int32 |
| 290 | | C_int64 of int64 |
| 291 | | C_float of float |
| 292 | | C_double of float |
| 293 | | C_ptr of int64 * int64 |
| 294 | | C_array of c_obj array |
| 295 | | C_list of c_obj list |
| 296 | | C_obj of (string -> c_obj -> c_obj) |
| 297 | | C_string of string |
| 298 | | C_enum of c_enum_t |
| 299 | </pre></div> |
| 300 | |
| 301 | <p> |
| 302 | A few functions exist which generate and return these: |
| 303 | </p> |
| 304 | |
| 305 | <ul> |
| 306 | <li>caml_ptr_val receives a c_obj and returns a void *. This |
| 307 | should be used for all pointer purposes.</li> |
| 308 | <li>caml_long_val receives a c_obj and returns a long. This |
| 309 | should be used for most integral purposes.<br> |
| 310 | </li> |
| 311 | <li>caml_val_ptr receives a void * and returns a c_obj.</li> |
| 312 | <li>caml_val_bool receives a C int and returns a c_obj representing |
| 313 | it's bool value.</li> |
| 314 | <li>caml_val_(u)?(char|short|int|long|float|double) receives an |
| 315 | appropriate C value and returns a c_obj representing it.</li> |
| 316 | <li>caml_val_string receives a char * and returns a string value.</li> |
| 317 | <li>caml_val_string_len receives a char * and a length and returns |
| 318 | a string value.</li> |
| 319 | <li>caml_val_obj receives a void * and an object type and returns |
| 320 | a C_obj, which contains a closure giving method access.</li> |
| 321 | |
| 322 | </ul> |
| 323 | |
| 324 | <p> |
| 325 | Because of this style, a typemap can return any kind of value it |
| 326 | wants from a function. This enables out typemaps and inout typemaps |
| 327 | to work well. The one thing to remember about outputting values |
| 328 | is that you must append them to the return list with swig_result = caml_list_append(swig_result,v). |
| 329 | </p> |
| 330 | |
| 331 | <p> |
| 332 | This function will return a new list that has your element |
| 333 | appended. Upon return to caml space, the fnhelper function |
| 334 | beautifies the result. A list containing a single item degrades to |
| 335 | only that item (i.e. [ C_int 3 ] -> C_int 3), and a list |
| 336 | containing more than one item is wrapped in C_list (i.e. [ C_char |
| 337 | 'a' ; C_char 'b' -> C_list [ C_char 'a' ; C_char b |
| 338 | ]). This is in order to make return values easier to handle |
| 339 | when functions have only one return value, such as constructors, |
| 340 | and operators. In addition, string, pointer, and object |
| 341 | values are interchangable with respect to caml_ptr_val, so you can |
| 342 | allocate memory as caml strings and still use the resulting |
| 343 | pointers for C purposes, even using them to construct simple objects |
| 344 | on. Note, though, that foreign C++ code does not respect the garbage |
| 345 | collector, although the SWIG interface does.</p> |
| 346 | |
| 347 | <p> |
| 348 | The wild card type that you can use in lots of different ways is |
| 349 | C_obj. It allows you to wrap any type of thing you like as an |
| 350 | object using the same mechanism that the ocaml module |
| 351 | does. When evaluated in caml_ptr_val, the returned value is |
| 352 | the result of a call to the object's "&" operator, taken as a pointer. |
| 353 | </p> |
| 354 | <p> |
| 355 | You should only construct values using objective caml, or using the |
| 356 | functions caml_val_* functions provided as static functions to a SWIG |
| 357 | ocaml module, as well as the caml_list_* functions. These functions |
| 358 | provide everything a typemap needs to produce values. In addition, |
| 359 | value items pass through directly, but you must make your own type |
| 360 | signature for a function that uses value in this way. |
| 361 | </p> |
| 362 | |
| 363 | <H3><a name="Ocaml_nn9"></a>22.2.1 The generated module</H3> |
| 364 | |
| 365 | |
| 366 | <p> |
| 367 | The SWIG <tt>%module</tt> directive specifies the name of the Ocaml |
| 368 | module to be generated. If you specified `<tt>%module example</tt>', |
| 369 | then your Ocaml code will be accessible in the module Example. The |
| 370 | module name is always capitalized as is the ocaml convention. Note |
| 371 | that you must not use any Ocaml keyword to name your module. Remember |
| 372 | that the keywords are not the same as the C++ ones. |
| 373 | </p> |
| 374 | |
| 375 | <p> |
| 376 | You can introduce extra code into the output wherever you like with SWIG. |
| 377 | These are the places you can introduce code: |
| 378 | <table border="1" summary="Extra code sections"> |
| 379 | <tr><td>"header"</td><td>This code is inserted near the beginning of the |
| 380 | C wrapper file, before any function definitions.</td></tr> |
| 381 | <tr><td>"wrapper"</td><td>This code is inserted in the function definition |
| 382 | section.</td></tr> |
| 383 | <tr><td>"runtime"</td><td>This code is inserted near the end of the C wrapper |
| 384 | file.</td></tr> |
| 385 | <tr><td>"mli"</td><td>This code is inserted into the caml interface file. |
| 386 | Special signatures should be inserted here. |
| 387 | </td></tr> |
| 388 | <tr><td>"ml"</td><td>This code is inserted in the caml code defining the |
| 389 | interface to your C code. Special caml code, as well as any initialization |
| 390 | which should run when the module is loaded may be inserted here. |
| 391 | </td></tr> |
| 392 | <tr><td>"classtemplate"</td><td>The "classtemplate" place is special because |
| 393 | it describes the output SWIG will generate for class definitions. |
| 394 | </td></tr> |
| 395 | </table> |
| 396 | |
| 397 | <H3><a name="Ocaml_nn10"></a>22.2.2 Enums</H3> |
| 398 | |
| 399 | |
| 400 | <p> |
| 401 | SWIG will wrap enumerations as polymorphic variants in the output |
| 402 | Ocaml code, as above in C_enum. In order to support all |
| 403 | C++-style uses of enums, the function int_to_enum and enum_to_int are |
| 404 | provided for ocaml code to produce and consume these values as |
| 405 | integers. Other than that, correct uses of enums will not have |
| 406 | a problem. Since enum labels may overlap between enums, the |
| 407 | enum_to_int and int_to_enum functions take an enum type label as an |
| 408 | argument. Example: |
| 409 | </p> |
| 410 | |
| 411 | <div class="code"><pre> |
| 412 | %module enum_test |
| 413 | %{ |
| 414 | enum c_enum_type { a = 1, b, c = 4, d = 8 }; |
| 415 | %} |
| 416 | enum c_enum_type { a = 1, b, c = 4, d = 8 }; |
| 417 | </pre></div> |
| 418 | |
| 419 | <p> |
| 420 | The output mli contains: |
| 421 | </p> |
| 422 | |
| 423 | <div class="code"><pre> |
| 424 | type c_enum_type = [ |
| 425 | `unknown |
| 426 | | `c_enum_type |
| 427 | ] |
| 428 | type c_enum_tag = [ |
| 429 | `int of int |
| 430 | | `a |
| 431 | | `b |
| 432 | | `c |
| 433 | | `d |
| 434 | ] |
| 435 | val int_to_enum c_enum_type -> int -> c_obj |
| 436 | val enum_to_int c_enum_type -> c_obj -> c_obj |
| 437 | </pre> |
| 438 | </div> |
| 439 | |
| 440 | <p> |
| 441 | So it's possible to do this: |
| 442 | </p> |
| 443 | |
| 444 | <div class="code"> |
| 445 | <pre> |
| 446 | bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top |
| 447 | bash-2.05a$ ./enum_test_top |
| 448 | Objective Caml version 3.04 |
| 449 | |
| 450 | # open Enum_test ;; |
| 451 | # let x = C_enum `a ;; |
| 452 | val x : Enum_test.c_obj = C_enum `a |
| 453 | # enum_to_int `c_enum_type x ;; |
| 454 | - : Enum_test.c_obj = C_int 1 |
| 455 | # int_to_enum `c_enum_type 4 ;; |
| 456 | - : Enum_test.c_obj = C_enum `c |
| 457 | </pre> |
| 458 | </div> |
| 459 | |
| 460 | <H4><a name="Ocaml_nn11"></a>22.2.2.1 Enum typing in Ocaml</H4> |
| 461 | |
| 462 | |
| 463 | <p> |
| 464 | The ocaml SWIG module now has support for loading and using multiple SWIG |
| 465 | modules at the same time. This enhances modularity, but presents problems |
| 466 | when used with a language which assumes that each module's types are complete |
| 467 | at compile time. In order to achieve total soundness enum types are now |
| 468 | isolated per-module. The type issue matters when values are shared between |
| 469 | functions imported from different modules. You must convert values to master |
| 470 | values using the swig_val function before sharing them with another module. |
| 471 | </p> |
| 472 | |
| 473 | <H3><a name="Ocaml_nn12"></a>22.2.3 Arrays</H3> |
| 474 | |
| 475 | |
| 476 | <H4><a name="Ocaml_nn13"></a>22.2.3.1 Simple types of bounded arrays</H4> |
| 477 | |
| 478 | |
| 479 | <p> |
| 480 | SWIG has support for array types, but you generally will need to provide |
| 481 | a typemap to handle them. You can currently roll your own, or expand |
| 482 | some of the macros provided (but not included by default) with the SWIG |
| 483 | distribution. |
| 484 | </p> |
| 485 | |
| 486 | <p> |
| 487 | By including "carray.i", you will get access to some macros that help you |
| 488 | create typemaps for array types fairly easily. |
| 489 | </p> |
| 490 | |
| 491 | <p> |
| 492 | <tt>%make_simple_array_typemap</tt> is the easiest way to get access to |
| 493 | arrays of simple types with known bounds in your code, but this only works |
| 494 | for arrays whose bounds are completely specified. |
| 495 | </p> |
| 496 | |
| 497 | <H4><a name="Ocaml_nn14"></a>22.2.3.2 Complex and unbounded arrays</H4> |
| 498 | |
| 499 | |
| 500 | <p> |
| 501 | Unfortunately, unbounded arrays and pointers can't be handled in a |
| 502 | completely general way by SWIG, because the end-condition of such an |
| 503 | array can't be predicted. In some cases, it will be by consent |
| 504 | (e.g. an array of four or more chars), sometimes by explicit length |
| 505 | (char *buffer, int len), and sometimes by sentinel value (0,-1,etc.). |
| 506 | SWIG can't predict which of these methods will be used in the array, |
| 507 | so you have to specify it for yourself in the form of a typemap. |
| 508 | </p> |
| 509 | |
| 510 | <H4><a name="Ocaml_nn15"></a>22.2.3.3 Using an object</H4> |
| 511 | |
| 512 | |
| 513 | <p> |
| 514 | It's possible to use C++ to your advantage by creating a simple object that |
| 515 | provides access to your array. This may be more desirable in some cases, |
| 516 | since the object can provide bounds checking, etc., that prevents crashes. |
| 517 | </p> |
| 518 | |
| 519 | <p> |
| 520 | Consider writing an object when the ending condition of your array is complex, |
| 521 | such as using a required centinel, etc. |
| 522 | </p> |
| 523 | |
| 524 | <H4><a name="Ocaml_nn16"></a>22.2.3.4 Example typemap for a function taking float * and int</H4> |
| 525 | |
| 526 | |
| 527 | <p> |
| 528 | This is a simple example <tt>in</tt> typemap for an array of float, where the |
| 529 | length of the array is specified as an extra parameter. Other such typemaps |
| 530 | will work similarly. In the example, the function printfloats is called with |
| 531 | a float array, and specified length. The actual length reported in the len |
| 532 | argument is the length of the array passed from ocaml, making passing an array |
| 533 | into this type of function convenient. |
| 534 | </p> |
| 535 | |
| 536 | <table border="1" bgcolor="#dddddd" summary="float * and int typemap example"> |
| 537 | <tr><th><center>tarray.i</center></th></tr> |
| 538 | <tr><td><pre> |
| 539 | %module tarray |
| 540 | %{ |
| 541 | #include <stdio.h> |
| 542 | |
| 543 | void printfloats( float *tab, int len ) { |
| 544 | int i; |
| 545 | |
| 546 | for( i = 0; i < len; i++ ) { |
| 547 | printf( "%f ", tab[i] ); |
| 548 | } |
| 549 | |
| 550 | printf( "\n" ); |
| 551 | } |
| 552 | %} |
| 553 | |
| 554 | %typemap(in) (float *tab, int len) { |
| 555 | int i; |
| 556 | /* $*1_type */ |
| 557 | $2 = caml_array_len($input); |
| 558 | $1 = ($*1_type *)malloc( $2 * sizeof( float ) ); |
| 559 | for( i = 0; i < $2; i++ ) { |
| 560 | $1[i] = caml_double_val(caml_array_nth($input,i)); |
| 561 | } |
| 562 | } |
| 563 | |
| 564 | void printfloats( float *tab, int len ); |
| 565 | </pre></td></tr> |
| 566 | <tr><th>Sample Run</th></tr> |
| 567 | <tr><td><pre> |
| 568 | # open Tarray ;; |
| 569 | # _printfloats (C_array [| C_double 1.0 ; C_double 3.0 ; C_double 5.6666 |]) ;; |
| 570 | 1.000000 3.000000 5.666600 |
| 571 | - : Tarray.c_obj = C_void |
| 572 | </pre></td></tr></table> |
| 573 | |
| 574 | |
| 575 | <H3><a name="Ocaml_nn17"></a>22.2.4 C++ Classes</H3> |
| 576 | |
| 577 | |
| 578 | <p> |
| 579 | C++ classes, along with structs and unions are represented by C_obj |
| 580 | (string -> c_obj -> c_obj) wrapped closures. These objects |
| 581 | contain a method list, and a type, which allow them to be used like |
| 582 | C++ objects. When passed into typemaps that use pointers, they |
| 583 | degrade to pointers through their "&" method. Every method |
| 584 | an object has is represented as a string in the object's method table, |
| 585 | and each method table exists in memory only once. In addition |
| 586 | to any other operators an object might have, certain builtin ones are |
| 587 | provided by SWIG: (all of these take no arguments (C_void)) |
| 588 | </p> |
| 589 | |
| 590 | <table summary="SWIG provided operators"> |
| 591 | <tr><td>"~"</td><td>Delete this object</td></tr> |
| 592 | <tr><td>"&"</td><td>Return an ordinary C_ptr value representing this |
| 593 | object's address</td></tr> |
| 594 | <tr><td>"sizeof"</td><td>If enabled with ("sizeof"="1") on the module node, |
| 595 | return the object's size in char.</td></tr> |
| 596 | <tr><td>":methods"</td><td>Returns a list of strings containing the names of |
| 597 | the methods this object contains</td></tr> |
| 598 | <tr><td>":classof"</td><td>Returns the name of the class this object belongs |
| 599 | to.</td></tr> |
| 600 | <tr><td>":parents"</td><td>Returns a list of all direct parent classes which |
| 601 | have been wrapped by SWIG.</td></tr> |
| 602 | <tr><td>"::[parent-class]"</td><td>Returns a view of the object as the |
| 603 | indicated parent class. This is mainly used internally by the SWIG module, |
| 604 | but may be useful to client programs.</td></tr> |
| 605 | <tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a |
| 606 | method with an optional parameter. |
| 607 | Called with one argument, the member variable is set to the value of the |
| 608 | argument. With zero arguments, the value is returned. |
| 609 | </td></tr> |
| 610 | </table> |
| 611 | |
| 612 | <p> |
| 613 | Note that this string belongs to the wrapper object, and not |
| 614 | the underlying pointer, so using create_[x]_from_ptr alters the |
| 615 | returned value for the same object. |
| 616 | </p> |
| 617 | |
| 618 | <H4><a name="Ocaml_nn18"></a>22.2.4.1 STL vector and string Example</H4> |
| 619 | |
| 620 | |
| 621 | <p> |
| 622 | Standard typemaps are now provided for STL vector and string. More are in |
| 623 | the works. STL strings are passed just like normal strings, and returned |
| 624 | as strings. STL string references don't mutate the original string, (which |
| 625 | might be surprising), because Ocaml strings are mutable but have fixed |
| 626 | length. Instead, use multiple returns, as in the argout_ref example. |
| 627 | </p> |
| 628 | |
| 629 | <table border="1" bgcolor="#dddddd" summary="STL vector and string example"> |
| 630 | <tr><th><center>example.i</center></th></tr> |
| 631 | <tr><td><pre> |
| 632 | %module example |
| 633 | %{ |
| 634 | #include "example.h" |
| 635 | %} |
| 636 | |
| 637 | %include stl.i |
| 638 | |
| 639 | namespace std { |
| 640 | %template(StringVector) std::vector < string >; |
| 641 | }; |
| 642 | |
| 643 | %include example.h |
| 644 | </pre></td></tr> |
| 645 | <tr><td><font size="-1"><i>This example is in Examples/ocaml/stl |
| 646 | </i></font></td></tr> |
| 647 | </table> |
| 648 | |
| 649 | <p> |
| 650 | Since there's a makefile in that directory, the example is easy to build. |
| 651 | </p> |
| 652 | |
| 653 | <p> |
| 654 | Here's a sample transcript of an interactive session using a string vector |
| 655 | after making a toplevel (make toplevel). This example uses the camlp4 |
| 656 | module. |
| 657 | </p> |
| 658 | |
| 659 | <div class="code"><pre> |
| 660 | bash-2.05a$ ./example_top |
| 661 | Objective Caml version 3.06 |
| 662 | |
| 663 | Camlp4 Parsing version 3.06 |
| 664 | |
| 665 | # open Swig ;; |
| 666 | # open Example ;; |
| 667 | # let x = new_StringVector '() ;; |
| 668 | val x : Example.c_obj = C_obj <fun> |
| 669 | # x -> ":methods" () ;; |
| 670 | - : Example.c_obj = |
| 671 | C_list |
| 672 | [C_string "nop"; C_string "size"; C_string "empty"; C_string "clear"; |
| 673 | C_string "push_back"; C_string "[]"; C_string "="; C_string "set"; |
| 674 | C_string "~"; C_string "&"; C_string ":parents"; C_string ":classof"; |
| 675 | C_string ":methods"] |
| 676 | # x -> push_back ("foo") ;; |
| 677 | - : Example.c_obj = C_void |
| 678 | # x -> push_back ("bar") ;; |
| 679 | - : Example.c_obj = C_void |
| 680 | # x -> push_back ("baz") ;; |
| 681 | - : Example.c_obj = C_void |
| 682 | # x '[1] ;; |
| 683 | - : Example.c_obj = C_string "bar" |
| 684 | # x -> set (1,"spam") ;; |
| 685 | - : Example.c_obj = C_void |
| 686 | # x '[1] ;; |
| 687 | - : Example.c_obj = C_string "spam" |
| 688 | # for i = 0 to (x -> size() as int) - 1 do |
| 689 | print_endline ((x '[i to int]) as string) |
| 690 | done ;; |
| 691 | foo |
| 692 | bar |
| 693 | baz |
| 694 | - : unit = () |
| 695 | # |
| 696 | </pre></div> |
| 697 | |
| 698 | <H4><a name="Ocaml_nn19"></a>22.2.4.2 C++ Class Example</H4> |
| 699 | |
| 700 | |
| 701 | <p> |
| 702 | Here's a simple example using Trolltech's Qt Library: |
| 703 | </p> |
| 704 | |
| 705 | <table border="1" bgcolor="#dddddd" summary="Qt Library example"> |
| 706 | <tr><th><center>qt.i</center></th></tr> |
| 707 | <tr><td><pre> |
| 708 | %module qt |
| 709 | %{ |
| 710 | #include <qapplication.h> |
| 711 | #include <qpushbutton.h> |
| 712 | %} |
| 713 | class QApplication { |
| 714 | public: |
| 715 | QApplication( int argc, char **argv ); |
| 716 | void setMainWidget( QWidget *widget ); |
| 717 | void exec(); |
| 718 | }; |
| 719 | |
| 720 | class QPushButton { |
| 721 | public: |
| 722 | QPushButton( char *str, QWidget *w ); |
| 723 | void resize( int x, int y ); |
| 724 | void show(); |
| 725 | }; |
| 726 | </pre></td></tr></table> |
| 727 | |
| 728 | <H4><a name="Ocaml_nn20"></a>22.2.4.3 Compiling the example</H4> |
| 729 | |
| 730 | |
| 731 | <div class="code"><pre> |
| 732 | bash-2.05a$ QTPATH=/your/qt/path |
| 733 | bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done |
| 734 | bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml |
| 735 | bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml |
| 736 | bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i |
| 737 | bash-2.05a$ mv qt_wrap.cxx qt_wrap.c |
| 738 | bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c |
| 739 | bash-2.05a$ ocamlc -c qt.mli |
| 740 | bash-2.05a$ ocamlc -c qt.ml |
| 741 | bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \ |
| 742 | camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \ |
| 743 | -L$QTPATH/lib -cclib -lqt |
| 744 | </pre></div> |
| 745 | |
| 746 | <H4><a name="Ocaml_nn21"></a>22.2.4.4 Sample Session</H4> |
| 747 | |
| 748 | |
| 749 | <div class="code"><pre> |
| 750 | bash-2.05a$ ./qt_top |
| 751 | Objective Caml version 3.06 |
| 752 | |
| 753 | Camlp4 Parsing version 3.06 |
| 754 | |
| 755 | # open Swig ;; |
| 756 | # open Qt ;; |
| 757 | # let a = new_QApplication '(0,0) ;; |
| 758 | val a : Qt.c_obj = C_obj <fun> |
| 759 | # let hello = new_QPushButton '("hi",0) ;; |
| 760 | val hello : Qt.c_obj = C_obj <fun> |
| 761 | # hello -> resize (100,30) ;; |
| 762 | - : Qt.c_obj = C_void |
| 763 | # hello -> show () ;; |
| 764 | - : Qt.c_obj = C_void |
| 765 | # a -> exec () ;; |
| 766 | </pre></div> |
| 767 | |
| 768 | <p> |
| 769 | Assuming you have a working installation of QT, you will see a window |
| 770 | containing the string "hi" in a button. |
| 771 | </p> |
| 772 | |
| 773 | <H3><a name="Ocaml_nn22"></a>22.2.5 Director Classes</H3> |
| 774 | |
| 775 | |
| 776 | <H4><a name="Ocaml_nn23"></a>22.2.5.1 Director Introduction</H4> |
| 777 | |
| 778 | |
| 779 | <p> |
| 780 | Director classes are classes which allow Ocaml code to override the public |
| 781 | methods of a C++ object. This facility allows the user to use C++ libraries |
| 782 | that require a derived class to provide application specific functionality in |
| 783 | the context of an application or utility framework. |
| 784 | </p> |
| 785 | |
| 786 | <p> |
| 787 | You can turn on director classes by using an optional module argument like |
| 788 | this: |
| 789 | </p> |
| 790 | |
| 791 | <div class="code"><pre> |
| 792 | %module(directors="1") |
| 793 | |
| 794 | ... |
| 795 | |
| 796 | // Turn on the director class for a specific class like this: |
| 797 | %feature("director") |
| 798 | class foo { |
| 799 | ... |
| 800 | }; |
| 801 | </pre></div> |
| 802 | |
| 803 | <H4><a name="Ocaml_nn24"></a>22.2.5.2 Overriding Methods in Ocaml</H4> |
| 804 | |
| 805 | |
| 806 | <p> |
| 807 | Because the Ocaml language module treats C++ method calls as calls to a |
| 808 | certain function, all you need to do is to define the function that will |
| 809 | handle the method calls in terms of the public methods of the object, and |
| 810 | any other relevant information. The function <tt>new_derived_object</tt> |
| 811 | uses a stub class to call your methods in place of the ones provided by the |
| 812 | underlying implemenation. The object you receive is the underlying object, |
| 813 | so you are free to call any methods you want from within your derived method. |
| 814 | Note that calls to the underlying object do not invoke Ocaml code. You need |
| 815 | to handle that yourself. |
| 816 | </p> |
| 817 | |
| 818 | <p> |
| 819 | <tt>new_derived_object</tt> receives your function, the function that creates |
| 820 | the underlying object, and any constructor arguments, and provides an |
| 821 | object that you can use in any usual way. When C++ code calls one of the |
| 822 | object's methods, the object invokes the Ocaml function as if it had been |
| 823 | invoked from Ocaml, allowing any method definitions to override the C++ ones. |
| 824 | </p> |
| 825 | |
| 826 | <p> |
| 827 | In this example, I'll examine the objective caml code involved in providing |
| 828 | an overloaded class. This example is contained in Examples/ocaml/shapes. |
| 829 | </p> |
| 830 | |
| 831 | <H4><a name="Ocaml_nn25"></a>22.2.5.3 Director Usage Example</H4> |
| 832 | |
| 833 | |
| 834 | <table border="1" bgcolor="#dddddd" summary="Director usage example"> |
| 835 | <tr><th><center>example_prog.ml</center> |
| 836 | </th></tr> |
| 837 | <tr><td><pre> |
| 838 | open Swig |
| 839 | open Example |
| 840 | |
| 841 | ... |
| 842 | |
| 843 | let triangle_class pts ob meth args = |
| 844 | match meth with |
| 845 | "cover" -> |
| 846 | (match args with |
| 847 | C_list [ x_arg ; y_arg ] -> |
| 848 | let xa = x_arg as float |
| 849 | and ya = y_arg as float in |
| 850 | (point_in_triangle pts xa ya) to bool |
| 851 | | _ -> raise (Failure "cover needs two double arguments.")) |
| 852 | | _ -> (invoke ob) meth args ;; |
| 853 | |
| 854 | let triangle = |
| 855 | new_derived_object |
| 856 | new_shape |
| 857 | (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) |
| 858 | '() ;; |
| 859 | |
| 860 | let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;; |
| 861 | </pre></td></tr> |
| 862 | </table> |
| 863 | |
| 864 | <p> |
| 865 | This is the meat of what you need to do. The actual "class" definition |
| 866 | containing the overloaded method is defined in the function triangle_class. |
| 867 | This is a lot like the class definitions emitted by SWIG, if you look at |
| 868 | example.ml, which is generated when SWIG consumes example.i. Basically, |
| 869 | you are given the arguments as a c_obj and the method name as a string, and |
| 870 | you must intercept the method you are interested in and provide whatever |
| 871 | return value you need. Bear in mind that the underlying C++ code needs the |
| 872 | right return type, or an exception will be thrown. This exception will |
| 873 | generally be Failure, or NotObject. You must call other ocaml methods that |
| 874 | you rely on yourself. Due to the way directors are implemented, method |
| 875 | calls on your object from with ocaml code will always invoke C++ methods |
| 876 | even if they are overridden in ocaml. |
| 877 | </p> |
| 878 | |
| 879 | <p> |
| 880 | In the example, the draw_shape_coverage function plots the indicated number |
| 881 | of points as either covered (<tt>x</tt>) or uncovered ( ) between |
| 882 | 0 and 1 on the X and Y axes. Your shape implementation can provide any |
| 883 | coverage map it likes, as long as it responds to the "cover" method call |
| 884 | with a boolean return (the underlying method returns bool). This might allow |
| 885 | a tricky shape implementation, such as a boolean combination, to be expressed |
| 886 | in a more effortless style in ocaml, while leaving the "engine" part of the |
| 887 | program in C++. |
| 888 | </p> |
| 889 | |
| 890 | <H4><a name="Ocaml_nn26"></a>22.2.5.4 Creating director objects</H4> |
| 891 | |
| 892 | |
| 893 | <p> |
| 894 | The definition of the actual object triangle can be described this way: |
| 895 | </p> |
| 896 | |
| 897 | <div class="code"><pre> |
| 898 | let triangle = |
| 899 | new_derived_object |
| 900 | new_shape |
| 901 | (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) |
| 902 | '() |
| 903 | </pre></div> |
| 904 | |
| 905 | <p> |
| 906 | The first argument to <tt>new_derived_object</tt>, new_shape is the method |
| 907 | which returns a shape instance. This function will be invoked with the |
| 908 | third argument will be appended to the argument list [ C_void ]. In the |
| 909 | example, the actual argument list is sent as (C_list [ C_void ; C_void ]). |
| 910 | The augmented constructor for a director class needs the first argument |
| 911 | to determine whether it is being constructed as a derived object, or as |
| 912 | an object of the indicated type only (in this case <tt>shape</tt>). The |
| 913 | Second argument is a closure that will be added to the final C_obj. |
| 914 | </p> |
| 915 | |
| 916 | <p> |
| 917 | The actual object passed to the self parameter of the director object will |
| 918 | be a C_director_core, containing a c_obj option ref and a c_obj. The |
| 919 | c_obj provided is the same object that will be returned from new_derived |
| 920 | object, that is, the object exposing the overridden methods. The other part |
| 921 | is an option ref that will have its value extracted before becoming the |
| 922 | <tt>ob</tt> parameter of your class closure. This ref will contain |
| 923 | <tt>None</tt> if the C++ object underlying is ever destroyed, and will |
| 924 | consequently trigger an exception when any method is called on the object |
| 925 | after that point (the actual raise is from an inner function used by |
| 926 | new_derived_object, and throws NotObject). This prevents a deleted C++ |
| 927 | object from causing a core dump, as long as the object is destroyed |
| 928 | properly. |
| 929 | </p> |
| 930 | |
| 931 | <H4><a name="Ocaml_nn27"></a>22.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4> |
| 932 | |
| 933 | |
| 934 | <p> |
| 935 | Special typemaps exist for use with directors, the <tt>directorin, directorout, directorargout</tt> |
| 936 | are used in place of <tt>in, out, argout</tt> typemaps, except that their |
| 937 | direction is reversed. They provide for you to provide argout values, as |
| 938 | well as a function return value in the same way you provide function arguments, |
| 939 | and to receive arguments the same way you normally receive function returns. |
| 940 | </p> |
| 941 | |
| 942 | <H4><a name="Ocaml_nn28"></a>22.2.5.6 <tt>directorin</tt> typemap</H4> |
| 943 | |
| 944 | |
| 945 | <p> |
| 946 | The <tt>directorin</tt> typemap is used when you will receive arguments from a call |
| 947 | made by C++ code to you, therefore, values will be translated from C++ to |
| 948 | ocaml. You must provide some valid C_obj value. This is the value your ocaml |
| 949 | code receives when you are called. In general, a simple <tt>directorin</tt> typemap |
| 950 | can use the same body as a simple <tt>out</tt> typemap. |
| 951 | </p> |
| 952 | |
| 953 | <H4><a name="Ocaml_nn29"></a>22.2.5.7 <tt>directorout</tt> typemap</H4> |
| 954 | |
| 955 | |
| 956 | <p> |
| 957 | The <tt>directorout</tt> typemap is used when you will send an argument from your |
| 958 | code back to the C++ caller. That is; directorout specifies a function return |
| 959 | conversion. You can usually use the same body as an <tt>in</tt> typemap |
| 960 | for the same type, except when there are special requirements for object |
| 961 | ownership, etc. |
| 962 | </p> |
| 963 | |
| 964 | <H4><a name="Ocaml_nn30"></a>22.2.5.8 <tt>directorargout</tt> typemap</H4> |
| 965 | |
| 966 | |
| 967 | <p> |
| 968 | C++ allows function arguments which are by pointer (*) and by reference (&) |
| 969 | to receive a value from the called function, as well as sending one there. |
| 970 | Sometimes, this is the main purpose of the argument given. <tt>directorargout</tt> |
| 971 | typemaps allow your caml code to emulate this by specifying additional return |
| 972 | values to be put into the output parameters. The SWIG ocaml module is a bit |
| 973 | loose in order to make code eaiser to write. In this case, your return to |
| 974 | the caller must be a list containing the normal function return first, followed |
| 975 | by any argout values in order. These argout values will be taken from the |
| 976 | list and assigned to the values to be returned to C++ through directorargout typemaps. |
| 977 | In the event that you don't specify all of the necessary values, integral |
| 978 | values will read zero, and struct or object returns have undefined results. |
| 979 | </p> |
| 980 | |
| 981 | <H3><a name="Ocaml_nn31"></a>22.2.6 Exceptions</H3> |
| 982 | |
| 983 | |
| 984 | <p> |
| 985 | Catching exceptions is now supported using SWIG's %exception feature. A simple |
| 986 | but not too useful example is provided by the throw_exception testcase in |
| 987 | Examples/test-suite. You can provide your own exceptions, too. |
| 988 | </p> |
| 989 | |
| 990 | </body> |
| 991 | </html> |