Thousands of changes to correct incorrect HTML. HTML is now valid (transitional 4.01).

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6074 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2004-08-04 21:28:14 +00:00
commit aa4d1d907d
31 changed files with 6754 additions and 4801 deletions

View file

@ -6,47 +6,47 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a>
<a name="n1"></a><H1>19 SWIG and Ocaml</H1>
<H1><a name="Ocaml"></a>21 SWIG and Ocaml</H1>
<!-- INDEX -->
<ul>
<li><a href="#n2">Preliminaries</a>
<li><a href="#Ocaml_nn2">Preliminaries</a>
<ul>
<li><a href="#n3">Running SWIG</a>
<li><a href="#n4">Compiling the code</a>
<li><a href="#n5">The camlp4 module</a>
<li><a href="#n6">Using your module</a>
<li><a href="#n7">Compilation problems and compiling with C++</a>
<li><a href="#Ocaml_nn3">Running SWIG</a>
<li><a href="#Ocaml_nn4">Compiling the code</a>
<li><a href="#Ocaml_nn5">The camlp4 module</a>
<li><a href="#Ocaml_nn6">Using your module</a>
<li><a href="#Ocaml_nn7">Compilation problems and compiling with C++</a>
</ul>
<li><a href="#n8">The low-level Ocaml/C interface</a>
<li><a href="#Ocaml_nn8">The low-level Ocaml/C interface</a>
<ul>
<li><a href="#n9">The generated module</a>
<li><a href="#n10">Enums</a>
<li><a href="#n11">Arrays</a>
<li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#Ocaml_nn10">Enums</a>
<li><a href="#Ocaml_nn11">Arrays</a>
<ul>
<li><a href="#n12">Simple types of bounded arrays</a>
<li><a href="#n13">Complex and unbounded arrays</a>
<li><a href="#n14">Using an object</a>
<li><a href="#n15">Example typemap for a function taking float * and int</a>
<li><a href="#Ocaml_nn12">Simple types of bounded arrays</a>
<li><a href="#Ocaml_nn13">Complex and unbounded arrays</a>
<li><a href="#Ocaml_nn14">Using an object</a>
<li><a href="#Ocaml_nn15">Example typemap for a function taking float * and int</a>
</ul>
<li><a href="#n16">C++ Classes</a>
<li><a href="#Ocaml_nn16">C++ Classes</a>
<ul>
<li><a href="#n17">STL vector and string Example</a>
<li><a href="#n18">C++ Class Example</a>
<li><a href="#n19">Compiling the example</a>
<li><a href="#n20">Sample Session</a>
<li><a href="#Ocaml_nn17">STL vector and string Example</a>
<li><a href="#Ocaml_nn18">C++ Class Example</a>
<li><a href="#Ocaml_nn19">Compiling the example</a>
<li><a href="#Ocaml_nn20">Sample Session</a>
</ul>
<li><a href="#n21">Director Classes</a>
<li><a href="#Ocaml_nn21">Director Classes</a>
<ul>
<li><a href="#n22">Director Introduction</a>
<li><a href="#n23">Overriding Methods in Ocaml</a>
<li><a href="#n24">Director Usage Example</a>
<li><a href="#n25">Creating director objects</a>
<li><a href="#n26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#n27"><tt>directorin</tt> typemap</a>
<li><a href="#n28"><tt>directorout</tt> typemap</a>
<li><a href="#n29"><tt>directorargout</tt> typemap</a>
<li><a href="#Ocaml_nn22">Director Introduction</a>
<li><a href="#Ocaml_nn23">Overriding Methods in Ocaml</a>
<li><a href="#Ocaml_nn24">Director Usage Example</a>
<li><a href="#Ocaml_nn25">Creating director objects</a>
<li><a href="#Ocaml_nn26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#Ocaml_nn27"><tt>directorin</tt> typemap</a>
<li><a href="#Ocaml_nn28"><tt>directorout</tt> typemap</a>
<li><a href="#Ocaml_nn29"><tt>directorargout</tt> typemap</a>
</ul>
<li><a href="#n30">Exceptions</a>
<li><a href="#Ocaml_nn30">Exceptions</a>
</ul>
</ul>
<!-- INDEX -->
@ -73,7 +73,7 @@ If you're not familiar with the Objective Caml language, you can visit
<a href="http://www.ocaml.org/">The Ocaml Website</a>.
</p>
<a name="n2"></a><H2>19.1 Preliminaries</H2>
<H2><a name="Ocaml_nn2"></a>21.1 Preliminaries</H2>
SWIG 1.3 works with Ocaml 3.04 and above. Given the choice,
@ -90,7 +90,7 @@ usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
file Examples/Makefile illustrate how to compile and link SWIG modules that
will be loaded dynamically. This has only been tested on Linux so far.
<a name="n3"></a><H3>19.1.1 Running SWIG</H3>
<H3><a name="Ocaml_nn3"></a>21.1.1 Running SWIG</H3>
The basics of getting a SWIG Ocaml module up and running
@ -99,7 +99,9 @@ will be loaded dynamically. This has only been tested on Linux so far.
option.
<blockquote>
<pre>%swig -ocaml example.i</pre>
<pre>
%swig -ocaml example.i
</pre>
</blockquote>
<p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains
@ -109,9 +111,10 @@ you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
the resulting .ml and .mli files as well, and do the final link with -custom
(not needed for native link). </p>
<a name="n4"></a><H3>19.1.2 Compiling the code</H3>
<H3><a name="Ocaml_nn4"></a>21.1.2 Compiling the code</H3>
<p>
The O'Caml SWIG module now requires you to compile a module (<tt>Swig</tt>)
separately. In addition to aggregating common SWIG functionality, the Swig
module contains the data structure that represents C/C++ values. This allows
@ -122,7 +125,7 @@ the user more freedom with respect to custom typing.
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
SWIG interface like:
<p> </p>
</p>
<blockquote>
<pre>
@ -131,38 +134,47 @@ the user more freedom with respect to custom typing.
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
% ocamlc -c example.mli
% ocamlc -c example.ml
</blockquote>
</pre>
</blockquote>
<p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately,
it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked
in C++ mode, you must: </p>
<blockquote>
<pre>% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br></pre>
</blockquote>
<pre>
% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br>
</pre>
</blockquote>
<a name="n5"></a><H3>19.1.3 The camlp4 module</H3>
<H3><a name="Ocaml_nn5"></a>21.1.3 The camlp4 module</H3>
<p>
The camlp4 module (swigp4.ml -&gt; swigp4.cmo) contains a simple rewriter which
makes C++ code blend more seamlessly with objective caml code. It's use is
optional, but encouraged. The source file is included in the Lib/ocaml
directory of the SWIG source distribution. You can checkout this file with
<tt>"swig -ocaml -co swigp4.ml"</tt>. You should compile the file with
<tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt>
</p>
<p>
The basic principle of the module is to recognize certain non-caml expressions
and convert them for use with C++ code as interfaced by SWIG. The camlp4
module is written to work with generated SWIG interfaces, and probably isn't
great to use with anything else.
</p>
<p>
Here are the main rewriting rules:
<p>
<table border="1">
</p>
<table border="1" summary="Rewriting rules">
<tr><th>Input</th><th>Rewritten to</th></tr>
<tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td>
<td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr>
<tr><td>object -> method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td>object -&gt; method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td>
object <i>'binop</i> argument as in<br>
a '+= b</td>
@ -178,9 +190,9 @@ and &gt;&gt;, they are replaced by lsl and lsr in operator names.
(invoke a) "!" C_void</td></tr>
<tr><td>
<b>Smart pointer access like this</b><br>
object '-> method ( args )<br>
object '-&gt; method ( args )<br>
</td><td>
(invoke (invoke object "->" C_void))
(invoke (invoke object "-&gt;" C_void))
</td></tr>
<tr><td>
<b>Invoke syntax</b><br>
@ -211,37 +223,47 @@ let b = C_string (getenv "PATH")
</td></tr>
</table>
<a name="n6"></a><H3>19.1.4 Using your module</H3>
<H3><a name="Ocaml_nn6"></a>21.1.4 Using your module</H3>
You can test-drive your module by building a
<p>
You can test-drive your module by building a
toplevel ocaml interpreter. Consult the ocaml manual for details.
</p>
<p>When linking any ocaml bytecode with your module, use the -custom
<p>
When linking any ocaml bytecode with your module, use the -custom
option to build your functions into the primitive list. This
option is not needed when you build native code.
</p>
<a name="n7"></a><H3>19.1.5 Compilation problems and compiling with C++</H3>
<H3><a name="Ocaml_nn7"></a>21.1.5 Compilation problems and compiling with C++</H3>
As mentioned above, .cxx files need special
<p>
As mentioned above, .cxx files need special
handling to be compiled with <tt>ocamlc</tt>. Other than that, C code
that uses <tt>class</tt> as a non-keyword, and C code that is too
liberal with pointer types may not compile under the C++ compiler.
Most code meant to be compiled as C++ will not have problems.
</p>
<a name="n8"></a><H2>19.2 The low-level Ocaml/C interface</H2>
<H2><a name="Ocaml_nn8"></a>21.2 The low-level Ocaml/C interface</H2>
In order to provide access to overloaded functions, and
<p>
In order to provide access to overloaded functions, and
provide sensible outputs from them, all C entites are represented as
members of the c_obj type:
</p>
<p>
In the code as seen by the typemap
writer, there is a value, swig_result, that always contains the
current return data. It is a list, and must be appended with the
caml_list_append function, or with functions and macros provided by
objective caml.<br>
</p>
<blockquote><pre>
type c_obj =
@ -284,11 +306,15 @@ appropriate C value and returns a c_obj representing it.</li>
a C_obj, which contains a closure giving method access.</li>
</ul>
Because of this style, a typemap can return any kind of value it
<p>
Because of this style, a typemap can return any kind of value it
wants from a function. &nbsp;This enables out typemaps and inout typemaps
to work well. &nbsp;The one thing to remember about outputting values
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).<p>
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).
</p>
<p>
&nbsp;This function will return a new list that has your element
appended. Upon return to caml space, the fnhelper function
beautifies the result. A list containing a single item degrades to
@ -302,13 +328,15 @@ is that you must append them to the return list with swig_result = caml_list_a
allocate memory as caml strings and still use the resulting
pointers for C purposes, even using them to construct simple objects
on. Note, though, that foreign C++ code does not respect the garbage
collector, although the SWIG interface does.<p>
collector, although the SWIG interface does.</p>
<p>
The wild card type that you can use in lots of different ways is
C_obj. It allows you to wrap any type of thing you like as an
object using the same mechanism that the ocaml module
does. &nbsp;When evaluated in caml_ptr_val, the returned value is
the result of a call to the object's "&" operator, taken as a pointer.
the result of a call to the object's "&amp;" operator, taken as a pointer.
</p>
<p>
You should only construct values using objective caml, or using the
functions caml_val_* functions provided as static functions to a SWIG
@ -316,20 +344,24 @@ is that you must append them to the return list with swig_result = caml_list_a
provide everything a typemap needs to produce values. In addition,
value items pass through directly, but you must make your own type
signature for a function that uses value in this way.
</p>
<a name="n9"></a><H3>19.2.1 The generated module</H3>
<H3><a name="Ocaml_nn9"></a>21.2.1 The generated module</H3>
<p>
The SWIG <tt>%module</tt> directive specifies the name of the Ocaml
module to be generated. If you specified `<tt>%module example</tt>',
then your Ocaml code will be accessible in the module Example. The
module name is always capitalized as is the ocaml convention. Note
that you must not use any Ocaml keyword to name your module. Remember
that the keywords are not the same as the C++ ones. <p>
that the keywords are not the same as the C++ ones.
</p>
<p>
You can introduce extra code into the output wherever you like with SWIG.
These are the places you can introduce code:
<table border="1">
<table border="1" summary="Extra code sections">
<tr><td>"header"</td><td>This code is inserted near the beginning of the
C wrapper file, before any function definitions.</td></tr>
<tr><td>"wrapper"</td><td>This code is inserted in the function definition
@ -345,11 +377,13 @@ which should run when the module is loaded may be inserted here.
</td></tr>
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
it describes the output SWIG will generate for class definitions.
</td></tr>
</table>
<a name="n10"></a><H3>19.2.2 Enums</H3>
<H3><a name="Ocaml_nn10"></a>21.2.2 Enums</H3>
<p>
SWIG will wrap enumerations as polymorphic variants in the output
Ocaml code, as above in C_enum.&nbsp; In order to support all
C++-style uses of enums, the function int_to_enum and enum_to_int are
@ -358,7 +392,8 @@ integers. &nbsp;Other than that, correct uses of enums will not have
a problem. &nbsp;Since enum labels may overlap between enums, the
enum_to_int and int_to_enum functions take an enum type label as an
argument. Example:
<p>
</p>
<blockquote><pre>
%module enum_test
%{
@ -366,9 +401,11 @@ enum c_enum_type { a = 1, b, c = 4, d = 8 };
%}
enum c_enum_type { a = 1, b, c = 4, d = 8 };
</pre></blockquote>
<p>
The output mli contains:
<p>
</p>
<blockquote><pre>
type c_enum_type = [
`unknown
@ -387,7 +424,8 @@ val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</blockquote>
So it's possible to do this:
<blockquote>
<pre>bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
<pre>
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
bash-2.05a$ ./enum_test_top
Objective Caml version 3.04
@ -401,12 +439,10 @@ val x : Enum_test.c_obj = C_enum `a
</pre>
</blockquote>
<p> </p>
<a name="n11"></a><H3>19.2.3 Arrays</H3>
<H3><a name="Ocaml_nn11"></a>21.2.3 Arrays</H3>
<a name="n12"></a><H4>19.2.3.1 Simple types of bounded arrays</H4>
<H4><a name="Ocaml_nn12"></a>21.2.3.1 Simple types of bounded arrays</H4>
<p>
@ -414,6 +450,7 @@ SWIG has support for array types, but you generally will need to provide
a typemap to handle them. You can currently roll your own, or expand
some of the macros provided (but not included by default) with the SWIG
distribution.
</p>
<p>
By including "carray.i", you will get access to some macros that help you
@ -426,7 +463,7 @@ arrays of simple types with known bounds in your code, but this only works
for arrays whose bounds are completely specified.
</p>
<a name="n13"></a><H4>19.2.3.2 Complex and unbounded arrays</H4>
<H4><a name="Ocaml_nn13"></a>21.2.3.2 Complex and unbounded arrays</H4>
<p>
@ -439,7 +476,7 @@ SWIG can't predict which of these methods will be used in the array,
so you have to specify it for yourself in the form of a typemap.
</p>
<a name="n14"></a><H4>19.2.3.3 Using an object</H4>
<H4><a name="Ocaml_nn14"></a>21.2.3.3 Using an object</H4>
<p>
@ -453,7 +490,7 @@ Consider writing an object when the ending condition of your array is complex,
such as using a required centinel, etc.
</p>
<a name="n15"></a><H4>19.2.3.4 Example typemap for a function taking float * and int</H4>
<H4><a name="Ocaml_nn15"></a>21.2.3.4 Example typemap for a function taking float * and int</H4>
<p>
@ -465,11 +502,12 @@ argument is the length of the array passed from ocaml, making passing an array
into this type of function convenient.
</p>
<table border="1" bgcolor="#dddddd"><tr><th><center>tarray.i</center></th></tr>
<table border="1" bgcolor="#dddddd" summary="float * and int typemap example">
<tr><th><center>tarray.i</center></th></tr>
<tr><td><pre>
%module tarray
%{
#include <stdio.h>
#include &lt;stdio.h&gt;
void printfloats( float *tab, int len ) {
int i;
@ -503,7 +541,7 @@ void printfloats( float *tab, int len );
</pre></td></tr></table>
<a name="n16"></a><H3>19.2.4 C++ Classes</H3>
<H3><a name="Ocaml_nn16"></a>21.2.4 C++ Classes</H3>
C++ classes, along with structs and unions are represented by C_obj
@ -515,7 +553,8 @@ an object has is represented as a string in the object's method table,
and each method table exists in memory only once. &nbsp;In addition
to any other operators an object might have, certain builtin ones are
provided by SWIG: (all of these take no arguments (C_void))
<table>
<table summary="SWIG provided operators">
<tr><td>"~"</td><td>Delete this object</td></tr>
<tr><td>"&amp;"</td><td>Return an ordinary C_ptr value representing this
object's address</td></tr>
@ -539,9 +578,8 @@ argument. With zero arguments, the value is returned.
Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object.
<p>
<a name="n17"></a><H4>19.2.4.1 STL vector and string Example</H4>
<H4><a name="Ocaml_nn17"></a>21.2.4.1 STL vector and string Example</H4>
Standard typemaps are now provided for STL vector and string. More are in
@ -550,7 +588,8 @@ as strings. STL string references don't mutate the original string, (which
might be surprising), because Ocaml strings are mutable but have fixed
length. Instead, use multiple returns, as in the argout_ref example.
<table border="1" bgcolor="#dddddd"><tr><th><center>example.i</center></th></tr>
<table border="1" bgcolor="#dddddd" summary="STL vector and string example">
<tr><th><center>example.i</center></th></tr>
<tr><td><pre>
%module example
%{
@ -567,12 +606,17 @@ namespace std {
</pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</i></font></td></tr>
</table><p>
</table>
Since there's a makefile in that directory, the example is easy to build.<p>
<p>
Since there's a makefile in that directory, the example is easy to build.
</p>
<p>
Here's a sample transcript of an interactive session using a string vector
after making a toplevel (make toplevel). This example uses the camlp4
module.
</p>
<blockquote><pre>
bash-2.05a$ ./example_top
@ -583,27 +627,27 @@ bash-2.05a$ ./example_top
# open Swig ;;
# open Example ;;
# let x = new_StringVector '() ;;
val x : Example.c_obj = C_obj <fun>
# x -> ":methods" () ;;
val x : Example.c_obj = C_obj &lt;fun&gt;
# x -&gt; ":methods" () ;;
- : Example.c_obj =
C_list
[C_string "nop"; C_string "size"; C_string "empty"; C_string "clear";
C_string "push_back"; C_string "[]"; C_string "="; C_string "set";
C_string "~"; C_string "&"; C_string ":parents"; C_string ":classof";
C_string "~"; C_string "&amp;"; C_string ":parents"; C_string ":classof";
C_string ":methods"]
# x -> push_back ("foo") ;;
# x -&gt; push_back ("foo") ;;
- : Example.c_obj = C_void
# x -> push_back ("bar") ;;
# x -&gt; push_back ("bar") ;;
- : Example.c_obj = C_void
# x -> push_back ("baz") ;;
# x -&gt; push_back ("baz") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "bar"
# x -> set (1,"spam") ;;
# x -&gt; set (1,"spam") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "spam"
# for i = 0 to (x -> size() as int) - 1 do
# for i = 0 to (x -&gt; size() as int) - 1 do
print_endline ((x '[i to int]) as string)
done ;;
foo
@ -613,12 +657,13 @@ baz
#
</pre></blockquote>
<a name="n18"></a><H4>19.2.4.2 C++ Class Example</H4>
<H4><a name="Ocaml_nn18"></a>21.2.4.2 C++ Class Example</H4>
Here's a simple example using Trolltech's Qt Library:
<table border="1" bgcolor="#dddddd"><tr><th><center>qt.i</center></th></tr>
<table border="1" bgcolor="#dddddd" summary="Qt Library example">
<tr><th><center>qt.i</center></th></tr>
<tr><td><pre>
%module qt
%{
@ -638,9 +683,9 @@ public:
void resize( int x, int y );
void show();
};
</pre></td></tr></table><p>
</pre></td></tr></table>
<a name="n19"></a><H4>19.2.4.3 Compiling the example</H4>
<H4><a name="Ocaml_nn19"></a>21.2.4.3 Compiling the example</H4>
<blockquote><pre>
@ -658,7 +703,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt
</pre></blockquote>
<a name="n20"></a><H4>19.2.4.4 Sample Session</H4>
<H4><a name="Ocaml_nn20"></a>21.2.4.4 Sample Session</H4>
<blockquote><pre>
@ -670,33 +715,40 @@ bash-2.05a$ ./qt_top
# open Swig ;;
# open Qt ;;
# let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj <fun>
val a : Qt.c_obj = C_obj &lt;fun&gt;
# let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj <fun>
# hello -> resize (100,30) ;;
val hello : Qt.c_obj = C_obj &lt;fun&gt;
# hello -&gt; resize (100,30) ;;
- : Qt.c_obj = C_void
# hello -> show () ;;
# hello -&gt; show () ;;
- : Qt.c_obj = C_void
# a -> exec () ;;
</pre></blockquote><p>
# a -&gt; exec () ;;
</pre></blockquote>
<p>
Assuming you have a working installation of QT, you will see a window
containing the string "hi" in a button.
</p>
<a name="n21"></a><H3>19.2.5 Director Classes</H3>
<H3><a name="Ocaml_nn21"></a>21.2.5 Director Classes</H3>
<a name="n22"></a><H4>19.2.5.1 Director Introduction</H4>
<H4><a name="Ocaml_nn22"></a>21.2.5.1 Director Introduction</H4>
<p>
Director classes are classes which allow Ocaml code to override the public
methods of a C++ object. This facility allows the user to use C++ libraries
that require a derived class to provide application specific functionality in
the context of an application or utility framework.
</p>
<p>
You can turn on director classes by using an optional module argument like
this:
<pre><blockquote><p>
</p>
<blockquote><pre>
%module(directors="1")
...
@ -706,9 +758,9 @@ this:
class foo {
...
};
</p></blockquote></pre>
</pre></blockquote>
<a name="n23"></a><H4>19.2.5.2 Overriding Methods in Ocaml</H4>
<H4><a name="Ocaml_nn23"></a>21.2.5.2 Overriding Methods in Ocaml</H4>
<p>
@ -721,21 +773,26 @@ underlying implemenation. The object you receive is the underlying object,
so you are free to call any methods you want from within your derived method.
Note that calls to the underlying object do not invoke Ocaml code. You need
to handle that yourself.
</p>
<p>
<tt>new_derived_object</tt> receives your function, the function that creates
the underlying object, and any constructor arguments, and provides an
object that you can use in any usual way. When C++ code calls one of the
object's methods, the object invokes the Ocaml function as if it had been
invoked from Ocaml, allowing any method definitions to override the C++ ones.
</p>
<p>
In this example, I'll examine the objective caml code involved in providing
an overloaded class. This example is contained in Examples/ocaml/shapes.
<p>
</p>
<a name="n24"></a><H4>19.2.5.3 Director Usage Example</H4>
<H4><a name="Ocaml_nn24"></a>21.2.5.3 Director Usage Example</H4>
<table border="1" bgcolor="#dddddd"><tr><th><center>example_prog.ml</center>
<table border="1" bgcolor="#dddddd" summary="Director usage example">
<tr><th><center>example_prog.ml</center>
</th></tr>
<tr><td><pre>
open Swig
@ -745,14 +802,14 @@ open Example
let triangle_class pts ob meth args =
match meth with
"cover" ->
"cover" -&gt;
(match args with
C_list [ x_arg ; y_arg ] ->
C_list [ x_arg ; y_arg ] -&gt;
let xa = x_arg as float
and ya = y_arg as float in
(point_in_triangle pts xa ya) to bool
| _ -> raise (Failure "cover needs two double arguments."))
| _ -> (invoke ob) meth args ;;
| _ -&gt; raise (Failure "cover needs two double arguments."))
| _ -&gt; (invoke ob) meth args ;;
let triangle =
new_derived_object
@ -763,6 +820,7 @@ let triangle =
let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;
</pre></td></tr>
</table>
<p>
This is the meat of what you need to do. The actual "class" definition
containing the overloaded method is defined in the function triangle_class.
@ -776,27 +834,31 @@ generally be Failure, or NotObject. You must call other ocaml methods that
you rely on yourself. Due to the way directors are implemented, method
calls on your object from with ocaml code will always invoke C++ methods
even if they are overridden in ocaml.
</p>
<p>
In the example, the draw_shape_coverage function plots the indicated number
of points as either covered (<tt>x</tt>) or uncovered (<tt> </tt>) between
of points as either covered (<tt>x</tt>) or uncovered ( ) between
0 and 1 on the X and Y axes. Your shape implementation can provide any
coverage map it likes, as long as it responds to the "cover" method call
with a boolean return (the underlying method returns bool). This might allow
a tricky shape implementation, such as a boolean combination, to be expressed
in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++.
<p>
<a name="n25"></a><H4>19.2.5.4 Creating director objects</H4>
</p>
<H4><a name="Ocaml_nn25"></a>21.2.5.4 Creating director objects</H4>
The definition of the actual object triangle can be described this way:
<pre><blockquote><p>
<blockquote><pre>
let triangle =
new_derived_object
new_shape
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
'()
</p></blockquote></pre>
</pre></blockquote>
<p>
The first argument to <tt>new_derived_object</tt>, new_shape is the method
which returns a shape instance. This function will be invoked with the
@ -806,6 +868,8 @@ The augmented constructor for a director class needs the first argument
to determine whether it is being constructed as a derived object, or as
an object of the indicated type only (in this case <tt>shape</tt>). The
Second argument is a closure that will be added to the final C_obj.
</p>
<p>
The actual object passed to the self parameter of the director object will
be a C_director_core, containing a c_obj option ref and a c_obj. The
@ -819,8 +883,9 @@ after that point (the actual raise is from an inner function used by
new_derived_object, and throws NotObject). This prevents a deleted C++
object from causing a core dump, as long as the object is destroyed
properly.
</p>
<a name="n26"></a><H4>19.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<H4><a name="Ocaml_nn26"></a>21.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<p>
@ -829,8 +894,9 @@ are used in place of <tt>in, out, argout</tt> typemaps, except that their
direction is reversed. They provide for you to provide argout values, as
well as a function return value in the same way you provide function arguments,
and to receive arguments the same way you normally receive function returns.
</P>
<a name="n27"></a><H4>19.2.5.6 <tt>directorin</tt> typemap</H4>
</p>
<H4><a name="Ocaml_nn27"></a>21.2.5.6 <tt>directorin</tt> typemap</H4>
<p>
@ -841,7 +907,7 @@ code receives when you are called. In general, a simple <tt>directorin</tt> typ
can use the same body as a simple <tt>out</tt> typemap.
</p>
<a name="n28"></a><H4>19.2.5.7 <tt>directorout</tt> typemap</H4>
<H4><a name="Ocaml_nn28"></a>21.2.5.7 <tt>directorout</tt> typemap</H4>
<p>
@ -852,11 +918,11 @@ for the same type, except when there are special requirements for object
ownership, etc.
</p>
<a name="n29"></a><H4>19.2.5.8 <tt>directorargout</tt> typemap</H4>
<H4><a name="Ocaml_nn29"></a>21.2.5.8 <tt>directorargout</tt> typemap</H4>
<p>
C++ allows function arguments which are by pointer (*) and by reference (&)
C++ allows function arguments which are by pointer (*) and by reference (&amp;)
to receive a value from the called function, as well as sending one there.
Sometimes, this is the main purpose of the argument given. <tt>directorargout</tt>
typemaps allow your caml code to emulate this by specifying additional return
@ -869,7 +935,7 @@ In the event that you don't specify all of the necessary values, integral
values will read zero, and struct or object returns have undefined results.
</p>
<a name="n30"></a><H3>19.2.6 Exceptions</H3>
<H3><a name="Ocaml_nn30"></a>21.2.6 Exceptions</H3>
Catching exceptions is now supported using SWIG's %exception feature. A simple