Updated documentation.

Provide a swig_val function which generates a shareable value from a module
specific one in a painless way.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6408 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Art Yerkes 2004-10-17 08:38:54 +00:00
commit e9160c8597
4 changed files with 83 additions and 53 deletions

View file

@ -21,32 +21,33 @@
<ul> <ul>
<li><a href="#Ocaml_nn9">The generated module</a> <li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#Ocaml_nn10">Enums</a> <li><a href="#Ocaml_nn10">Enums</a>
<li><a href="#Ocaml_nn11">Arrays</a> <li><a href="#Ocaml_nn11">Enum typing in Ocaml</a>
<li><a href="#Ocaml_nn12">Arrays</a>
<ul> <ul>
<li><a href="#Ocaml_nn12">Simple types of bounded arrays</a> <li><a href="#Ocaml_nn13">Simple types of bounded arrays</a>
<li><a href="#Ocaml_nn13">Complex and unbounded arrays</a> <li><a href="#Ocaml_nn14">Complex and unbounded arrays</a>
<li><a href="#Ocaml_nn14">Using an object</a> <li><a href="#Ocaml_nn15">Using an object</a>
<li><a href="#Ocaml_nn15">Example typemap for a function taking float * and int</a> <li><a href="#Ocaml_nn16">Example typemap for a function taking float * and int</a>
</ul> </ul>
<li><a href="#Ocaml_nn16">C++ Classes</a> <li><a href="#Ocaml_nn17">C++ Classes</a>
<ul> <ul>
<li><a href="#Ocaml_nn17">STL vector and string Example</a> <li><a href="#Ocaml_nn18">STL vector and string Example</a>
<li><a href="#Ocaml_nn18">C++ Class Example</a> <li><a href="#Ocaml_nn19">C++ Class Example</a>
<li><a href="#Ocaml_nn19">Compiling the example</a> <li><a href="#Ocaml_nn20">Compiling the example</a>
<li><a href="#Ocaml_nn20">Sample Session</a> <li><a href="#Ocaml_nn21">Sample Session</a>
</ul> </ul>
<li><a href="#Ocaml_nn21">Director Classes</a> <li><a href="#Ocaml_nn22">Director Classes</a>
<ul> <ul>
<li><a href="#Ocaml_nn22">Director Introduction</a> <li><a href="#Ocaml_nn23">Director Introduction</a>
<li><a href="#Ocaml_nn23">Overriding Methods in Ocaml</a> <li><a href="#Ocaml_nn24">Overriding Methods in Ocaml</a>
<li><a href="#Ocaml_nn24">Director Usage Example</a> <li><a href="#Ocaml_nn25">Director Usage Example</a>
<li><a href="#Ocaml_nn25">Creating director objects</a> <li><a href="#Ocaml_nn26">Creating director objects</a>
<li><a href="#Ocaml_nn26">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a> <li><a href="#Ocaml_nn27">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>directorin</tt> typemap</a>
<li><a href="#Ocaml_nn28"><tt>directorout</tt> typemap</a> <li><a href="#Ocaml_nn29"><tt>directorout</tt> typemap</a>
<li><a href="#Ocaml_nn29"><tt>directorargout</tt> typemap</a> <li><a href="#Ocaml_nn30"><tt>directorargout</tt> typemap</a>
</ul> </ul>
<li><a href="#Ocaml_nn30">Exceptions</a> <li><a href="#Ocaml_nn31">Exceptions</a>
</ul> </ul>
</ul> </ul>
<!-- INDEX --> <!-- INDEX -->
@ -438,11 +439,21 @@ val x : Enum_test.c_obj = C_enum `a
- : Enum_test.c_obj = C_enum `c - : Enum_test.c_obj = C_enum `c
</pre> </pre>
</blockquote> </blockquote>
<H3><a name="Ocaml_nn11"></a>22.2.3 Arrays</H3> <H4><a name="Ocaml_nn11"></a>22.2.2.1 Enum typing in Ocaml</H4>
The ocaml SWIG module now has support for loading and using multiple SWIG
modules at the same time. This enhances modularity, but presents problems
when used with a language which assumes that each module's types are complete
at compile time. In order to achieve total soundness enum types are now
isolated per-module. The type issue matters when values are shared between
functions imported from different modules. You must convert values to master
values using the swig_val function before sharing them with another module.
<H3><a name="Ocaml_nn12"></a>22.2.3 Arrays</H3>
<H4><a name="Ocaml_nn12"></a>22.2.3.1 Simple types of bounded arrays</H4> <H4><a name="Ocaml_nn13"></a>22.2.3.1 Simple types of bounded arrays</H4>
<p> <p>
@ -463,7 +474,7 @@ arrays of simple types with known bounds in your code, but this only works
for arrays whose bounds are completely specified. for arrays whose bounds are completely specified.
</p> </p>
<H4><a name="Ocaml_nn13"></a>22.2.3.2 Complex and unbounded arrays</H4> <H4><a name="Ocaml_nn14"></a>22.2.3.2 Complex and unbounded arrays</H4>
<p> <p>
@ -476,7 +487,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. so you have to specify it for yourself in the form of a typemap.
</p> </p>
<H4><a name="Ocaml_nn14"></a>22.2.3.3 Using an object</H4> <H4><a name="Ocaml_nn15"></a>22.2.3.3 Using an object</H4>
<p> <p>
@ -490,7 +501,7 @@ Consider writing an object when the ending condition of your array is complex,
such as using a required centinel, etc. such as using a required centinel, etc.
</p> </p>
<H4><a name="Ocaml_nn15"></a>22.2.3.4 Example typemap for a function taking float * and int</H4> <H4><a name="Ocaml_nn16"></a>22.2.3.4 Example typemap for a function taking float * and int</H4>
<p> <p>
@ -541,7 +552,7 @@ void printfloats( float *tab, int len );
</pre></td></tr></table> </pre></td></tr></table>
<H3><a name="Ocaml_nn16"></a>22.2.4 C++ Classes</H3> <H3><a name="Ocaml_nn17"></a>22.2.4 C++ Classes</H3>
C++ classes, along with structs and unions are represented by C_obj C++ classes, along with structs and unions are represented by C_obj
@ -579,7 +590,7 @@ Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object. returned value for the same object.
<H4><a name="Ocaml_nn17"></a>22.2.4.1 STL vector and string Example</H4> <H4><a name="Ocaml_nn18"></a>22.2.4.1 STL vector and string Example</H4>
Standard typemaps are now provided for STL vector and string. More are in Standard typemaps are now provided for STL vector and string. More are in
@ -657,7 +668,7 @@ baz
# #
</pre></blockquote> </pre></blockquote>
<H4><a name="Ocaml_nn18"></a>22.2.4.2 C++ Class Example</H4> <H4><a name="Ocaml_nn19"></a>22.2.4.2 C++ Class Example</H4>
Here's a simple example using Trolltech's Qt Library: Here's a simple example using Trolltech's Qt Library:
@ -685,7 +696,7 @@ public:
}; };
</pre></td></tr></table> </pre></td></tr></table>
<H4><a name="Ocaml_nn19"></a>22.2.4.3 Compiling the example</H4> <H4><a name="Ocaml_nn20"></a>22.2.4.3 Compiling the example</H4>
<blockquote><pre> <blockquote><pre>
@ -703,7 +714,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt -L$QTPATH/lib -cclib -lqt
</pre></blockquote> </pre></blockquote>
<H4><a name="Ocaml_nn20"></a>22.2.4.4 Sample Session</H4> <H4><a name="Ocaml_nn21"></a>22.2.4.4 Sample Session</H4>
<blockquote><pre> <blockquote><pre>
@ -730,10 +741,10 @@ 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_nn21"></a>22.2.5 Director Classes</H3> <H3><a name="Ocaml_nn22"></a>22.2.5 Director Classes</H3>
<H4><a name="Ocaml_nn22"></a>22.2.5.1 Director Introduction</H4> <H4><a name="Ocaml_nn23"></a>22.2.5.1 Director Introduction</H4>
<p> <p>
@ -760,7 +771,7 @@ class foo {
}; };
</pre></blockquote> </pre></blockquote>
<H4><a name="Ocaml_nn23"></a>22.2.5.2 Overriding Methods in Ocaml</H4> <H4><a name="Ocaml_nn24"></a>22.2.5.2 Overriding Methods in Ocaml</H4>
<p> <p>
@ -788,7 +799,7 @@ In this example, I'll examine the objective caml code involved in providing
an overloaded class. This example is contained in Examples/ocaml/shapes. an overloaded class. This example is contained in Examples/ocaml/shapes.
</p> </p>
<H4><a name="Ocaml_nn24"></a>22.2.5.3 Director Usage Example</H4> <H4><a name="Ocaml_nn25"></a>22.2.5.3 Director Usage Example</H4>
<table border="1" bgcolor="#dddddd" summary="Director usage example"> <table border="1" bgcolor="#dddddd" summary="Director usage example">
@ -847,7 +858,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++. program in C++.
</p> </p>
<H4><a name="Ocaml_nn25"></a>22.2.5.4 Creating director objects</H4> <H4><a name="Ocaml_nn26"></a>22.2.5.4 Creating director objects</H4>
The definition of the actual object triangle can be described this way: The definition of the actual object triangle can be described this way:
@ -885,7 +896,7 @@ object from causing a core dump, as long as the object is destroyed
properly. properly.
</p> </p>
<H4><a name="Ocaml_nn26"></a>22.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4> <H4><a name="Ocaml_nn27"></a>22.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<p> <p>
@ -896,7 +907,7 @@ 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. and to receive arguments the same way you normally receive function returns.
</p> </p>
<H4><a name="Ocaml_nn27"></a>22.2.5.6 <tt>directorin</tt> typemap</H4> <H4><a name="Ocaml_nn28"></a>22.2.5.6 <tt>directorin</tt> typemap</H4>
<p> <p>
@ -907,7 +918,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. can use the same body as a simple <tt>out</tt> typemap.
</p> </p>
<H4><a name="Ocaml_nn28"></a>22.2.5.7 <tt>directorout</tt> typemap</H4> <H4><a name="Ocaml_nn29"></a>22.2.5.7 <tt>directorout</tt> typemap</H4>
<p> <p>
@ -918,7 +929,7 @@ for the same type, except when there are special requirements for object
ownership, etc. ownership, etc.
</p> </p>
<H4><a name="Ocaml_nn29"></a>22.2.5.8 <tt>directorargout</tt> typemap</H4> <H4><a name="Ocaml_nn30"></a>22.2.5.8 <tt>directorargout</tt> typemap</H4>
<p> <p>
@ -935,7 +946,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. values will read zero, and struct or object returns have undefined results.
</p> </p>
<H3><a name="Ocaml_nn30"></a>22.2.6 Exceptions</H3> <H3><a name="Ocaml_nn31"></a>22.2.6 Exceptions</H3>
Catching exceptions is now supported using SWIG's %exception feature. A simple Catching exceptions is now supported using SWIG's %exception feature. A simple

View file

@ -3,7 +3,7 @@ enum GlobalEnum { globalenum1=1, globalenum2 };
/* This function should be static as it will be emitted into the code for /* This function should be static as it will be emitted into the code for
* every module. All _static targets would fail here with a multiple * every module. All _static targets would fail here with a multiple
* definition if this is not static. */ * definition if this is not static. */
GlobalEnum global_test(GlobalEnum e) { return e; } static GlobalEnum global_test(GlobalEnum e) { return e; }
class A { class A {
public: public:

View file

@ -12,6 +12,17 @@
/* Type registration */ /* Type registration */
%insert(init) "typeregister.swg" %insert(init) "typeregister.swg"
%insert(mlitail) %{
val swig_val : c_enum_type -> c_obj -> Swig.c_obj
%}
%insert(mltail) %{
let swig_val t v =
match v with
C_enum e -> enum_to_int t v
| _ -> Obj.magic v
%}
/*#ifndef SWIG_NOINCLUDE*/ /*#ifndef SWIG_NOINCLUDE*/
%insert(runtime) "ocaml.swg" %insert(runtime) "ocaml.swg"
/*#endif*/ /*#endif*/

View file

@ -56,6 +56,8 @@ static File *f_mlout = 0;
static File *f_mliout = 0; static File *f_mliout = 0;
static File *f_mlbody = 0; static File *f_mlbody = 0;
static File *f_mlibody = 0; static File *f_mlibody = 0;
static File *f_mltail = 0;
static File *f_mlitail = 0;
static File *f_enumtypes_type = 0; static File *f_enumtypes_type = 0;
static File *f_enumtypes_value = 0; static File *f_enumtypes_value = 0;
static File *f_class_ctors = 0; static File *f_class_ctors = 0;
@ -225,6 +227,8 @@ public:
init_func_def = NewString(""); init_func_def = NewString("");
f_mlbody = NewString(""); f_mlbody = NewString("");
f_mlibody = NewString(""); f_mlibody = NewString("");
f_mltail = NewString("");
f_mlitail = NewString("");
f_class_ctors = NewString(""); f_class_ctors = NewString("");
f_class_ctors_end = NewString(""); f_class_ctors_end = NewString("");
f_enum_to_int = NewString(""); f_enum_to_int = NewString("");
@ -244,6 +248,8 @@ public:
Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("runtime",f_runtime);
Swig_register_filebyname("mli",f_mlibody); Swig_register_filebyname("mli",f_mlibody);
Swig_register_filebyname("ml",f_mlbody); Swig_register_filebyname("ml",f_mlbody);
Swig_register_filebyname("mlitail",f_mlitail);
Swig_register_filebyname("mltail",f_mltail);
Swig_register_filebyname("director",f_directors); Swig_register_filebyname("director",f_directors);
Swig_register_filebyname("director_h",f_directors_h); Swig_register_filebyname("director_h",f_directors_h);
Swig_register_filebyname("classtemplate",f_classtemplate); Swig_register_filebyname("classtemplate",f_classtemplate);
@ -265,7 +271,7 @@ public:
" (let y = _y in match (x : c_enum_type) with\n" " (let y = _y in match (x : c_enum_type) with\n"
" `unknown -> " " `unknown -> "
" (match (Obj.magic y) with\n" " (match (Obj.magic y) with\n"
" `Int x -> C_int x\n" " `Int x -> Swig.C_int x\n"
" | _ -> raise (LabelNotFromThisEnum v))\n" ); " | _ -> raise (LabelNotFromThisEnum v))\n" );
Printf( f_int_to_enum, Printf( f_int_to_enum,
@ -305,11 +311,11 @@ public:
Language::top(n); Language::top(n);
Printf( f_enum_to_int, Printf( f_enum_to_int,
") | _ -> (C_int (get_int v))\n" ") | _ -> (Swig.C_int (get_int v))\n"
"let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n",
module ); module );
Printf( f_mlibody, Printf( f_mlibody,
"val enum_to_int : c_enum_type -> c_obj -> c_obj\n" ); "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n" );
Printf( f_int_to_enum, Printf( f_int_to_enum,
"let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n",
@ -351,12 +357,14 @@ public:
Delete(f_enum_to_int); Delete(f_enum_to_int);
Dump(f_class_ctors,f_mlout); Dump(f_class_ctors,f_mlout);
Dump(f_class_ctors_end,f_mlout); Dump(f_class_ctors_end,f_mlout);
Dump(f_mltail,f_mlout);
Close(f_mlout); Close(f_mlout);
Delete(f_mlout); Delete(f_mlout);
Dump(f_enumtypes_type,f_mliout); Dump(f_enumtypes_type,f_mliout);
Dump(f_enumtypes_value,f_mliout); Dump(f_enumtypes_value,f_mliout);
Dump(f_mlibody,f_mliout); Dump(f_mlibody,f_mliout);
Dump(f_mlitail,f_mliout);
Close(f_mliout); Close(f_mliout);
Delete(f_mliout); Delete(f_mliout);
@ -894,21 +902,21 @@ public:
if( Getattr( n, "feature:immutable" ) ) { if( Getattr( n, "feature:immutable" ) ) {
Printf( f_mlbody, Printf( f_mlbody,
"external _%s : c_obj -> c_obj = \"%s\" \n", "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\" \n",
mname, var_name ); mname, var_name );
Printf( f_mlibody, "val _%s : c_obj -> c_obj\n", iname ); Printf( f_mlibody, "val _%s : Swig.c_obj -> Swig.c_obj\n", iname );
if( const_enum ) { if( const_enum ) {
Printf( f_enum_to_int, Printf( f_enum_to_int,
" | `%s -> _%s C_void\n", " | `%s -> _%s Swig.C_void\n",
mname, mname ); mname, mname );
Printf( f_int_to_enum, Printf( f_int_to_enum,
" if y = (get_int (_%s C_void)) then `%s else\n", " if y = (get_int (_%s Swig.C_void)) then `%s else\n",
mname, mname ); mname, mname );
} }
} else { } else {
Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", Printf( f_mlbody, "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\"\n",
mname, var_name ); mname, var_name );
Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", Printf( f_mlibody, "external _%s : Swig.c_obj -> Swig.c_obj = \"%s\"\n",
mname, var_name ); mname, var_name );
} }
@ -1182,7 +1190,7 @@ public:
/* Insert sizeof operator for concrete classes */ /* Insert sizeof operator for concrete classes */
if( sizeof_feature ) { if( sizeof_feature ) {
Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", Printv(f_class_ctors, "\"sizeof\" , (fun args -> Swig.C_int (__",
classname, "_sizeof ())) ;\n", NIL); classname, "_sizeof ())) ;\n", NIL);
} }
/* Handle up-casts in a nice way */ /* Handle up-casts in a nice way */
@ -1421,7 +1429,7 @@ public:
if( const_enum ) { if( const_enum ) {
Printf( f_int_to_enum, "`Int y)\n" ); Printf( f_int_to_enum, "`Int y)\n" );
Printf( f_enum_to_int, Printf( f_enum_to_int,
"| `Int x -> C_int x\n" "| `Int x -> Swig.C_int x\n"
"| _ -> raise (LabelNotFromThisEnum v))\n" ); "| _ -> raise (LabelNotFromThisEnum v))\n" );
} }