Whitespace cleanup
This commit is contained in:
parent
064f18131d
commit
13894f803b
1 changed files with 155 additions and 153 deletions
|
|
@ -1,11 +1,11 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>SWIG and Ocaml</title>
|
<title>SWIG and Ocaml</title>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css">
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff">
|
|
||||||
<a name="n1"></a>
|
<body bgcolor="#ffffff">
|
||||||
<H1><a name="Ocaml"></a>31 SWIG and Ocaml</H1>
|
<H1><a name="Ocaml"></a>31 SWIG and Ocaml</H1>
|
||||||
<!-- INDEX -->
|
<!-- INDEX -->
|
||||||
<div class="sectiontoc">
|
<div class="sectiontoc">
|
||||||
|
|
@ -59,20 +59,23 @@
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This chapter describes SWIG's
|
This chapter describes SWIG's support of Ocaml.
|
||||||
support of Ocaml. Ocaml is a relatively recent addition to the ML family,
|
</p>
|
||||||
and is a recent addition to SWIG. It's the second compiled, typed
|
|
||||||
language to be added. Ocaml has widely acknowledged benefits for engineers,
|
<p>
|
||||||
mostly derived from a sophisticated type system, compile-time checking
|
Ocaml is a relatively recent addition to the ML family,
|
||||||
which eliminates several classes of common programming errors, and good
|
and is a recent addition to SWIG. It's the second compiled, typed
|
||||||
native performance. While all of this is wonderful, there are well-written
|
language to be added. Ocaml has widely acknowledged benefits for engineers,
|
||||||
C and C++ libraries that Ocaml users will want to take advantage of as
|
mostly derived from a sophisticated type system, compile-time checking
|
||||||
part of their arsenal (such as SSL and gdbm), as well as their own mature
|
which eliminates several classes of common programming errors, and good
|
||||||
C and C++ code. SWIG allows this code to be used in a natural, type-safe
|
native performance. While all of this is wonderful, there are well-written
|
||||||
way with Ocaml, by providing the necessary, but repetitive glue code
|
C and C++ libraries that Ocaml users will want to take advantage of as
|
||||||
which creates and uses Ocaml values to communicate with C and C++ code.
|
part of their arsenal (such as SSL and gdbm), as well as their own mature
|
||||||
In addition, SWIG also produces the needed Ocaml source that binds
|
C and C++ code. SWIG allows this code to be used in a natural, type-safe
|
||||||
variants, functions, classes, etc.
|
way with Ocaml, by providing the necessary, but repetitive glue code
|
||||||
|
which creates and uses Ocaml values to communicate with C and C++ code.
|
||||||
|
In addition, SWIG also produces the needed Ocaml source that binds
|
||||||
|
variants, functions, classes, etc.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -84,17 +87,16 @@ If you're not familiar with the Objective Caml language, you can visit
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
SWIG 3.0 works with Ocaml 3.08.3 and above. Given the choice,
|
SWIG 3.0 works with Ocaml 3.08.3 and above. Given the choice,
|
||||||
you should use the latest stable release. The SWIG Ocaml module has
|
you should use the latest stable release. The SWIG Ocaml module has
|
||||||
been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The
|
been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The
|
||||||
best way to determine whether your system will work is to compile the
|
best way to determine whether your system will work is to compile the
|
||||||
examples and test-suite which come with SWIG. You can do this by running
|
examples and test-suite which come with SWIG. You can do this by running
|
||||||
<tt>make check</tt> from the SWIG root directory after installing SWIG.
|
<tt>make check</tt> from the SWIG root directory after installing SWIG.
|
||||||
The Ocaml module has been tested using the system's dynamic linking (the
|
The Ocaml module has been tested using the system's dynamic linking (the
|
||||||
usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
|
usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
|
||||||
<a
|
<a href="http://download.camlcity.org/download/">Dl package</a>.
|
||||||
href="http://download.camlcity.org/download/">Dl package
|
The ocaml_dynamic and ocaml_dynamic_cpp targets in the
|
||||||
</a>. The ocaml_dynamic and ocaml_dynamic_cpp targets in the
|
|
||||||
file Examples/Makefile illustrate how to compile and link SWIG modules that
|
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.
|
will be loaded dynamically. This has only been tested on Linux so far.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -103,30 +105,30 @@ will be loaded dynamically. This has only been tested on Linux so far.
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The basics of getting a SWIG Ocaml module up and running
|
The basics of getting a SWIG Ocaml module up and running
|
||||||
can be seen from one of SWIG's example Makefiles, but is also described
|
can be seen from one of SWIG's example Makefiles, but is also described
|
||||||
here. To build an Ocaml module, run SWIG using the <tt>-ocaml</tt>
|
here. To build an Ocaml module, run SWIG using the <tt>-ocaml</tt>
|
||||||
option.
|
option.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%swig -ocaml example.i
|
%swig -ocaml example.i
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains
|
<p>This will produce 3 files. The file <tt>example_wrap.c</tt> contains
|
||||||
all of the C code needed to build an Ocaml module. To build the module,
|
all of the C code needed to build an Ocaml module. To build the module,
|
||||||
you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
|
you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
|
||||||
<tt>ocamlopt</tt> to create the needed .o file. You will need to compile
|
<tt>ocamlopt</tt> to create the needed .o file. You will need to compile
|
||||||
the resulting .ml and .mli files as well, and do the final link with -custom
|
the resulting .ml and .mli files as well, and do the final link with -custom
|
||||||
(not needed for native link). </p>
|
(not needed for native link).</p>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn4"></a>31.1.2 Compiling the code</H3>
|
<H3><a name="Ocaml_nn4"></a>31.1.2 Compiling the code</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The OCaml SWIG module now requires you to compile a module (<tt>Swig</tt>)
|
The OCaml SWIG module now requires you to compile a module (<tt>Swig</tt>)
|
||||||
separately. In addition to aggregating common SWIG functionality, the Swig
|
separately. In addition to aggregating common SWIG functionality, the Swig
|
||||||
module contains the data structure that represents C/C++ values. This allows
|
module contains the data structure that represents C/C++ values. This allows
|
||||||
easier data sharing between modules if two or more are combined, because
|
easier data sharing between modules if two or more are combined, because
|
||||||
|
|
@ -134,28 +136,29 @@ the type of each SWIG'ed module's c_obj is derived from Swig.c_obj_t. This
|
||||||
also allows SWIG to acquire new conversions painlessly, as well as giving
|
also allows SWIG to acquire new conversions painlessly, as well as giving
|
||||||
the user more freedom with respect to custom typing.
|
the user more freedom with respect to custom typing.
|
||||||
|
|
||||||
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
|
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your SWIG interface like:
|
||||||
SWIG interface like:
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml
|
% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml
|
||||||
% ocamlc -c swig.mli ; ocamlc -c swig.ml
|
% ocamlc -c swig.mli ; ocamlc -c swig.ml
|
||||||
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
|
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
|
||||||
% ocamlc -c example.mli
|
% ocamlc -c example.mli
|
||||||
% ocamlc -c example.ml
|
% ocamlc -c example.ml
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately,
|
<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
|
it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked
|
||||||
in C++ mode, you must: </p>
|
in C++ mode, you must:</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br>
|
% cp example_wrap.cxx example_wrap.cxx.c
|
||||||
</pre>
|
% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c
|
||||||
|
% ...
|
||||||
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn5"></a>31.1.3 The camlp4 module</H3>
|
<H3><a name="Ocaml_nn5"></a>31.1.3 The camlp4 module</H3>
|
||||||
|
|
@ -165,8 +168,8 @@ the user more freedom with respect to custom typing.
|
||||||
The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple rewriter which
|
The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple rewriter which
|
||||||
makes C++ code blend more seamlessly with objective caml code. Its use is
|
makes C++ code blend more seamlessly with objective caml code. Its use is
|
||||||
optional, but encouraged. The source file is included in the Lib/ocaml
|
optional, but encouraged. The source file is included in the Lib/ocaml
|
||||||
directory of the SWIG source distribution. You can checkout this file with
|
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>"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>
|
<tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -192,7 +195,7 @@ a '+= b</td>
|
||||||
<td>
|
<td>
|
||||||
(invoke object) "+=" argument as in<br>
|
(invoke object) "+=" argument as in<br>
|
||||||
(invoke a) "+=" b<td></tr>
|
(invoke a) "+=" b<td></tr>
|
||||||
<tr><th colspan=2>Note that because camlp4 always recognizes <<
|
<tr><th colspan=2>Note that because camlp4 always recognizes <<
|
||||||
and >>, they are replaced by lsl and lsr in operator names.
|
and >>, they are replaced by lsl and lsr in operator names.
|
||||||
<tr><td>
|
<tr><td>
|
||||||
<i>'unop</i> object as in<br>
|
<i>'unop</i> object as in<br>
|
||||||
|
|
@ -241,11 +244,11 @@ let b = C_string (getenv "PATH")
|
||||||
You can test-drive your module by building a
|
You can test-drive your module by building a
|
||||||
toplevel ocaml interpreter. Consult the ocaml manual for details.
|
toplevel ocaml interpreter. Consult the ocaml manual for details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When linking any ocaml bytecode with your module, use the -custom
|
When linking any ocaml bytecode with your module, use the -custom
|
||||||
option to build your functions into the primitive list. This
|
option to build your functions into the primitive list. This
|
||||||
option is not needed when you build native code.
|
option is not needed when you build native code.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn7"></a>31.1.5 Compilation problems and compiling with C++</H3>
|
<H3><a name="Ocaml_nn7"></a>31.1.5 Compilation problems and compiling with C++</H3>
|
||||||
|
|
@ -273,9 +276,9 @@ In the code as seen by the typemap
|
||||||
writer, there is a value, swig_result, that always contains the
|
writer, there is a value, swig_result, that always contains the
|
||||||
current return data. It is a list, and must be appended with 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
|
caml_list_append function, or with functions and macros provided by
|
||||||
objective caml.<br>
|
objective caml.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
type c_obj =
|
type c_obj =
|
||||||
C_void
|
C_void
|
||||||
|
|
@ -299,66 +302,65 @@ type c_obj =
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A few functions exist which generate and return these:
|
A few functions exist which generate and return these:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>caml_ptr_val receives a c_obj and returns a void *. This
|
<li>caml_ptr_val receives a c_obj and returns a void *. This
|
||||||
should be used for all pointer purposes.</li>
|
should be used for all pointer purposes.</li>
|
||||||
<li>caml_long_val receives a c_obj and returns a long. This
|
<li>caml_long_val receives a c_obj and returns a long. This
|
||||||
should be used for most integral purposes.<br>
|
should be used for most integral purposes.</li>
|
||||||
</li>
|
<li>caml_val_ptr receives a void * and returns a c_obj.</li>
|
||||||
<li>caml_val_ptr receives a void * and returns a c_obj.</li>
|
<li>caml_val_bool receives a C int and returns a c_obj representing
|
||||||
<li>caml_val_bool receives a C int and returns a c_obj representing
|
its bool value.</li>
|
||||||
its bool value.</li>
|
<li>caml_val_(u)?(char|short|int|long|float|double) receives an
|
||||||
<li>caml_val_(u)?(char|short|int|long|float|double) receives an
|
appropriate C value and returns a c_obj representing it.</li>
|
||||||
appropriate C value and returns a c_obj representing it.</li>
|
<li>caml_val_string receives a char * and returns a string value.</li>
|
||||||
<li>caml_val_string receives a char * and returns a string value.</li>
|
<li>caml_val_string_len receives a char * and a length and returns
|
||||||
<li>caml_val_string_len receives a char * and a length and returns
|
a string value.</li>
|
||||||
a string value.</li>
|
<li>caml_val_obj receives a void * and an object type and returns
|
||||||
<li>caml_val_obj receives a void * and an object type and returns
|
a C_obj, which contains a closure giving method access.</li>
|
||||||
a C_obj, which contains a closure giving method access.</li>
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Because of this style, a typemap can return any kind of value it
|
Because of this style, a typemap can return any kind of value it
|
||||||
wants from a function. This enables out typemaps and inout typemaps
|
wants from a function. This enables out typemaps and inout typemaps
|
||||||
to work well. The one thing to remember about outputting values
|
to work well. 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).
|
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This function will return a new list that has your element
|
This function will return a new list that has your element
|
||||||
appended. Upon return to caml space, the fnhelper function
|
appended. Upon return to caml space, the fnhelper function
|
||||||
beautifies the result. A list containing a single item degrades to
|
beautifies the result. A list containing a single item degrades to
|
||||||
only that item (i.e. [ C_int 3 ] -> C_int 3), and a list
|
only that item (i.e. [ C_int 3 ] -> C_int 3), and a list
|
||||||
containing more than one item is wrapped in C_list (i.e. [ C_char
|
containing more than one item is wrapped in C_list (i.e. [ C_char
|
||||||
'a' ; C_char 'b' -> C_list [ C_char 'a' ; C_char b
|
'a' ; C_char 'b' -> C_list [ C_char 'a' ; C_char b
|
||||||
]). This is in order to make return values easier to handle
|
]). This is in order to make return values easier to handle
|
||||||
when functions have only one return value, such as constructors,
|
when functions have only one return value, such as constructors,
|
||||||
and operators. In addition, string, pointer, and object
|
and operators. In addition, string, pointer, and object
|
||||||
values are interchangeable with respect to caml_ptr_val, so you can
|
values are interchangeable with respect to caml_ptr_val, so you can
|
||||||
allocate memory as caml strings and still use the resulting
|
allocate memory as caml strings and still use the resulting
|
||||||
pointers for C purposes, even using them to construct simple objects
|
pointers for C purposes, even using them to construct simple objects
|
||||||
on. Note, though, that foreign C++ code does not respect the garbage
|
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>
|
<p>
|
||||||
The wild card type that you can use in lots of different ways is
|
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
|
C_obj. It allows you to wrap any type of thing you like as an
|
||||||
object using the same mechanism that the ocaml module
|
object using the same mechanism that the ocaml module
|
||||||
does. When evaluated in caml_ptr_val, the returned value is
|
does. 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 "&" operator, taken as a pointer.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
You should only construct values using objective caml, or using the
|
<p>
|
||||||
functions caml_val_* functions provided as static functions to a SWIG
|
You should only construct values using objective caml, or using the
|
||||||
ocaml module, as well as the caml_list_* functions. These functions
|
functions caml_val_* functions provided as static functions to a SWIG
|
||||||
provide everything a typemap needs to produce values. In addition,
|
ocaml module, as well as the caml_list_* functions. These functions
|
||||||
value items pass through directly, but you must make your own type
|
provide everything a typemap needs to produce values. In addition,
|
||||||
signature for a function that uses value in this way.
|
value items pass through directly, but you must make your own type
|
||||||
</p>
|
signature for a function that uses value in this way.
|
||||||
|
</p>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn9"></a>31.2.1 The generated module</H3>
|
<H3><a name="Ocaml_nn9"></a>31.2.1 The generated module</H3>
|
||||||
|
|
||||||
|
|
@ -376,7 +378,7 @@ that the keywords are not the same as the C++ ones.
|
||||||
You can introduce extra code into the output wherever you like with SWIG.
|
You can introduce extra code into the output wherever you like with SWIG.
|
||||||
These are the places you can introduce code:
|
These are the places you can introduce code:
|
||||||
<table border="1" summary="Extra code sections">
|
<table border="1" summary="Extra code sections">
|
||||||
<tr><td>"header"</td><td>This code is inserted near the beginning of the
|
<tr><td>"header"</td><td>This code is inserted near the beginning of the
|
||||||
C wrapper file, before any function definitions.</td></tr>
|
C wrapper file, before any function definitions.</td></tr>
|
||||||
<tr><td>"wrapper"</td><td>This code is inserted in the function definition
|
<tr><td>"wrapper"</td><td>This code is inserted in the function definition
|
||||||
section.</td></tr>
|
section.</td></tr>
|
||||||
|
|
@ -385,25 +387,25 @@ file.</td></tr>
|
||||||
<tr><td>"mli"</td><td>This code is inserted into the caml interface file.
|
<tr><td>"mli"</td><td>This code is inserted into the caml interface file.
|
||||||
Special signatures should be inserted here.
|
Special signatures should be inserted here.
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>"ml"</td><td>This code is inserted in the caml code defining the
|
<tr><td>"ml"</td><td>This code is inserted in the caml code defining the
|
||||||
interface to your C code. Special caml code, as well as any initialization
|
interface to your C code. Special caml code, as well as any initialization
|
||||||
which should run when the module is loaded may be inserted here.
|
which should run when the module is loaded may be inserted here.
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
|
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
|
||||||
it describes the output SWIG will generate for class definitions.
|
it describes the output SWIG will generate for class definitions.
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn10"></a>31.2.2 Enums</H3>
|
<H3><a name="Ocaml_nn10"></a>31.2.2 Enums</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
SWIG will wrap enumerations as polymorphic variants in the output
|
SWIG will wrap enumerations as polymorphic variants in the output
|
||||||
Ocaml code, as above in C_enum. In order to support all
|
Ocaml code, as above in C_enum. In order to support all
|
||||||
C++-style uses of enums, the function int_to_enum and enum_to_int are
|
C++-style uses of enums, the function int_to_enum and enum_to_int are
|
||||||
provided for ocaml code to produce and consume these values as
|
provided for ocaml code to produce and consume these values as
|
||||||
integers. Other than that, correct uses of enums will not have
|
integers. Other than that, correct uses of enums will not have
|
||||||
a problem. Since enum labels may overlap between enums, the
|
a problem. Since enum labels may overlap between enums, the
|
||||||
enum_to_int and int_to_enum functions take an enum type label as an
|
enum_to_int and int_to_enum functions take an enum type label as an
|
||||||
argument. Example:
|
argument. Example:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -416,9 +418,9 @@ enum c_enum_type { a = 1, b, c = 4, d = 8 };
|
||||||
enum c_enum_type { a = 1, b, c = 4, d = 8 };
|
enum c_enum_type { a = 1, b, c = 4, d = 8 };
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The output mli contains:
|
The output mli contains:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
type c_enum_type = [
|
type c_enum_type = [
|
||||||
|
|
@ -435,16 +437,16 @@ type c_enum_tag = [
|
||||||
val int_to_enum c_enum_type -> int -> c_obj
|
val int_to_enum c_enum_type -> int -> c_obj
|
||||||
val enum_to_int c_enum_type -> c_obj -> c_obj
|
val enum_to_int c_enum_type -> c_obj -> c_obj
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
So it's possible to do this:
|
So it's possible to do this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
|
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
|
||||||
bash-2.05a$ ./enum_test_top
|
bash-2.05a$ ./enum_test_top
|
||||||
Objective Caml version 3.04
|
Objective Caml version 3.04
|
||||||
|
|
||||||
# open Enum_test ;;
|
# open Enum_test ;;
|
||||||
|
|
@ -455,7 +457,7 @@ val x : Enum_test.c_obj = C_enum `a
|
||||||
# int_to_enum `c_enum_type 4 ;;
|
# int_to_enum `c_enum_type 4 ;;
|
||||||
- : Enum_test.c_obj = C_enum `c
|
- : Enum_test.c_obj = C_enum `c
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<H4><a name="Ocaml_nn11"></a>31.2.2.1 Enum typing in Ocaml</H4>
|
<H4><a name="Ocaml_nn11"></a>31.2.2.1 Enum typing in Ocaml</H4>
|
||||||
|
|
||||||
|
|
@ -485,7 +487,7 @@ distribution.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
By including "carray.i", you will get access to some macros that help you
|
By including "carray.i", you will get access to some macros that help you
|
||||||
create typemaps for array types fairly easily.
|
create typemaps for array types fairly easily.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -547,7 +549,7 @@ void printfloats( float *tab, int len ) {
|
||||||
printf( "%f ", tab[i] );
|
printf( "%f ", tab[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
@ -577,25 +579,25 @@ void printfloats( float *tab, int len );
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
C++ classes, along with structs and unions are represented by C_obj
|
C++ classes, along with structs and unions are represented by C_obj
|
||||||
(string -> c_obj -> c_obj) wrapped closures. These objects
|
(string -> c_obj -> c_obj) wrapped closures. These objects
|
||||||
contain a method list, and a type, which allow them to be used like
|
contain a method list, and a type, which allow them to be used like
|
||||||
C++ objects. When passed into typemaps that use pointers, they
|
C++ objects. When passed into typemaps that use pointers, they
|
||||||
degrade to pointers through their "&" method. Every method
|
degrade to pointers through their "&" method. Every method
|
||||||
an object has is represented as a string in the object's method table,
|
an object has is represented as a string in the object's method table,
|
||||||
and each method table exists in memory only once. In addition
|
and each method table exists in memory only once. In addition
|
||||||
to any other operators an object might have, certain builtin ones are
|
to any other operators an object might have, certain builtin ones are
|
||||||
provided by SWIG: (all of these take no arguments (C_void))
|
provided by SWIG: (all of these take no arguments (C_void))
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table summary="SWIG provided operators">
|
<table summary="SWIG provided operators">
|
||||||
<tr><td>"~"</td><td>Delete this object</td></tr>
|
<tr><td>"~"</td><td>Delete this object</td></tr>
|
||||||
<tr><td>"&"</td><td>Return an ordinary C_ptr value representing this
|
<tr><td>"&"</td><td>Return an ordinary C_ptr value representing this
|
||||||
object's address</td></tr>
|
object's address</td></tr>
|
||||||
<tr><td>"sizeof"</td><td>If enabled with ("sizeof"="1") on the module node,
|
<tr><td>"sizeof"</td><td>If enabled with ("sizeof"="1") on the module node,
|
||||||
return the object's size in char.</td></tr>
|
return the object's size in char.</td></tr>
|
||||||
<tr><td>":methods"</td><td>Returns a list of strings containing the names of
|
<tr><td>":methods"</td><td>Returns a list of strings containing the names of
|
||||||
the methods this object contains</td></tr>
|
the methods this object contains</td></tr>
|
||||||
<tr><td>":classof"</td><td>Returns the name of the class this object belongs
|
<tr><td>":classof"</td><td>Returns the name of the class this object belongs
|
||||||
to.</td></tr>
|
to.</td></tr>
|
||||||
<tr><td>":parents"</td><td>Returns a list of all direct parent classes which
|
<tr><td>":parents"</td><td>Returns a list of all direct parent classes which
|
||||||
have been wrapped by SWIG.</td></tr>
|
have been wrapped by SWIG.</td></tr>
|
||||||
|
|
@ -603,8 +605,8 @@ have been wrapped by SWIG.</td></tr>
|
||||||
indicated parent class. This is mainly used internally by the SWIG module,
|
indicated parent class. This is mainly used internally by the SWIG module,
|
||||||
but may be useful to client programs.</td></tr>
|
but may be useful to client programs.</td></tr>
|
||||||
<tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a
|
<tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a
|
||||||
method with an optional parameter.
|
method with an optional parameter.
|
||||||
Called with one argument, the member variable is set to the value of the
|
Called with one argument, the member variable is set to the value of the
|
||||||
argument. With zero arguments, the value is returned.
|
argument. With zero arguments, the value is returned.
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -652,12 +654,12 @@ 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
|
Here's a sample transcript of an interactive session using a string vector
|
||||||
after making a toplevel (make toplevel). This example uses the camlp4
|
after making a toplevel (make toplevel). This example uses the camlp4
|
||||||
module.
|
module.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
bash-2.05a$ ./example_top
|
bash-2.05a$ ./example_top
|
||||||
Objective Caml version 3.06
|
Objective Caml version 3.06
|
||||||
|
|
||||||
Camlp4 Parsing version 3.06
|
Camlp4 Parsing version 3.06
|
||||||
|
|
@ -685,14 +687,14 @@ C_list
|
||||||
- : Example.c_obj = C_void
|
- : Example.c_obj = C_void
|
||||||
# x '[1] ;;
|
# x '[1] ;;
|
||||||
- : Example.c_obj = C_string "spam"
|
- : Example.c_obj = C_string "spam"
|
||||||
# for i = 0 to (x -> size() as int) - 1 do
|
# for i = 0 to (x -> size() as int) - 1 do
|
||||||
print_endline ((x '[i to int]) as string)
|
print_endline ((x '[i to int]) as string)
|
||||||
done ;;
|
done ;;
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
- : unit = ()
|
- : unit = ()
|
||||||
#
|
#
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<H4><a name="Ocaml_nn19"></a>31.2.4.2 C++ Class Example</H4>
|
<H4><a name="Ocaml_nn19"></a>31.2.4.2 C++ Class Example</H4>
|
||||||
|
|
@ -703,7 +705,7 @@ Here's a simple example using Trolltech's Qt Library:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table border="1" bgcolor="#dddddd" summary="Qt Library example">
|
<table border="1" bgcolor="#dddddd" summary="Qt Library example">
|
||||||
<tr><th><center>qt.i</center></th></tr>
|
<tr><th><center>qt.i</center></th></tr>
|
||||||
<tr><td><pre>
|
<tr><td><pre>
|
||||||
%module qt
|
%module qt
|
||||||
%{
|
%{
|
||||||
|
|
@ -733,9 +735,9 @@ bash-2.05a$ QTPATH=/your/qt/path
|
||||||
bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
|
bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
|
||||||
bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
|
bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
|
||||||
bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
|
bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
|
||||||
bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
|
bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
|
||||||
bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
|
bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
|
||||||
bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
|
bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
|
||||||
bash-2.05a$ ocamlc -c qt.mli
|
bash-2.05a$ ocamlc -c qt.mli
|
||||||
bash-2.05a$ ocamlc -c qt.ml
|
bash-2.05a$ ocamlc -c qt.ml
|
||||||
bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
|
bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
|
||||||
|
|
@ -747,7 +749,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
|
||||||
|
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
bash-2.05a$ ./qt_top
|
bash-2.05a$ ./qt_top
|
||||||
Objective Caml version 3.06
|
Objective Caml version 3.06
|
||||||
|
|
||||||
Camlp4 Parsing version 3.06
|
Camlp4 Parsing version 3.06
|
||||||
|
|
@ -767,7 +769,7 @@ val hello : Qt.c_obj = C_obj <fun>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Assuming you have a working installation of QT, you will see a window
|
Assuming you have a working installation of QT, you will see a window
|
||||||
containing the string "hi" in a button.
|
containing the string "hi" in a button.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H3><a name="Ocaml_nn22"></a>31.2.5 Director Classes</H3>
|
<H3><a name="Ocaml_nn22"></a>31.2.5 Director Classes</H3>
|
||||||
|
|
@ -852,7 +854,7 @@ let triangle_class pts ob meth args =
|
||||||
| _ -> (invoke ob) meth args ;;
|
| _ -> (invoke ob) meth args ;;
|
||||||
|
|
||||||
let triangle =
|
let triangle =
|
||||||
new_derived_object
|
new_derived_object
|
||||||
new_shape
|
new_shape
|
||||||
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
||||||
'() ;;
|
'() ;;
|
||||||
|
|
@ -896,7 +898,7 @@ The definition of the actual object triangle can be described this way:
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
let triangle =
|
let triangle =
|
||||||
new_derived_object
|
new_derived_object
|
||||||
new_shape
|
new_shape
|
||||||
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
|
||||||
'()
|
'()
|
||||||
|
|
@ -904,13 +906,13 @@ let triangle =
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The first argument to <tt>new_derived_object</tt>, new_shape is the method
|
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
|
which returns a shape instance. This function will be invoked with the
|
||||||
third argument will be appended to the argument list [ C_void ]. In the
|
third argument will be appended to the argument list [ C_void ]. In the
|
||||||
example, the actual argument list is sent as (C_list [ C_void ; C_void ]).
|
example, the actual argument list is sent as (C_list [ C_void ; C_void ]).
|
||||||
The augmented constructor for a director class needs the first argument
|
The augmented constructor for a director class needs the first argument
|
||||||
to determine whether it is being constructed as a derived object, or as
|
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
|
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.
|
Second argument is a closure that will be added to the final C_obj.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue