PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Doc/Manual/Ocaml.html

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