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:
parent
db57b0d6d8
commit
e9160c8597
4 changed files with 83 additions and 53 deletions
|
|
@ -21,32 +21,33 @@
|
|||
<ul>
|
||||
<li><a href="#Ocaml_nn9">The generated module</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>
|
||||
<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>
|
||||
<li><a href="#Ocaml_nn13">Simple types of bounded arrays</a>
|
||||
<li><a href="#Ocaml_nn14">Complex and unbounded arrays</a>
|
||||
<li><a href="#Ocaml_nn15">Using an object</a>
|
||||
<li><a href="#Ocaml_nn16">Example typemap for a function taking float * and int</a>
|
||||
</ul>
|
||||
<li><a href="#Ocaml_nn16">C++ Classes</a>
|
||||
<li><a href="#Ocaml_nn17">C++ Classes</a>
|
||||
<ul>
|
||||
<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>
|
||||
<li><a href="#Ocaml_nn18">STL vector and string Example</a>
|
||||
<li><a href="#Ocaml_nn19">C++ Class Example</a>
|
||||
<li><a href="#Ocaml_nn20">Compiling the example</a>
|
||||
<li><a href="#Ocaml_nn21">Sample Session</a>
|
||||
</ul>
|
||||
<li><a href="#Ocaml_nn21">Director Classes</a>
|
||||
<li><a href="#Ocaml_nn22">Director Classes</a>
|
||||
<ul>
|
||||
<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>
|
||||
<li><a href="#Ocaml_nn23">Director Introduction</a>
|
||||
<li><a href="#Ocaml_nn24">Overriding Methods in Ocaml</a>
|
||||
<li><a href="#Ocaml_nn25">Director Usage Example</a>
|
||||
<li><a href="#Ocaml_nn26">Creating director objects</a>
|
||||
<li><a href="#Ocaml_nn27">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
|
||||
<li><a href="#Ocaml_nn28"><tt>directorin</tt> typemap</a>
|
||||
<li><a href="#Ocaml_nn29"><tt>directorout</tt> typemap</a>
|
||||
<li><a href="#Ocaml_nn30"><tt>directorargout</tt> typemap</a>
|
||||
</ul>
|
||||
<li><a href="#Ocaml_nn30">Exceptions</a>
|
||||
<li><a href="#Ocaml_nn31">Exceptions</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -438,11 +439,21 @@ val x : Enum_test.c_obj = C_enum `a
|
|||
- : Enum_test.c_obj = C_enum `c
|
||||
</pre>
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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>
|
||||
|
|
@ -490,7 +501,7 @@ Consider writing an object when the ending condition of your array is complex,
|
|||
such as using a required centinel, etc.
|
||||
</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>
|
||||
|
|
@ -541,7 +552,7 @@ void printfloats( float *tab, int len );
|
|||
</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
|
||||
|
|
@ -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
|
||||
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
|
||||
|
|
@ -657,7 +668,7 @@ baz
|
|||
#
|
||||
</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:
|
||||
|
|
@ -685,7 +696,7 @@ public:
|
|||
};
|
||||
</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>
|
||||
|
|
@ -703,7 +714,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
|
|||
-L$QTPATH/lib -cclib -lqt
|
||||
</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>
|
||||
|
|
@ -730,10 +741,10 @@ Assuming you have a working installation of QT, you will see a window
|
|||
containing the string "hi" in a button.
|
||||
</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>
|
||||
|
|
@ -760,7 +771,7 @@ class foo {
|
|||
};
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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">
|
||||
|
|
@ -847,7 +858,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the
|
|||
program in C++.
|
||||
</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:
|
||||
|
|
@ -885,7 +896,7 @@ object from causing a core dump, as long as the object is destroyed
|
|||
properly.
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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>
|
||||
|
|
@ -918,7 +929,7 @@ for the same type, except when there are special requirements for object
|
|||
ownership, etc.
|
||||
</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>
|
||||
|
|
@ -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.
|
||||
</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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ enum GlobalEnum { globalenum1=1, globalenum2 };
|
|||
/* 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
|
||||
* definition if this is not static. */
|
||||
GlobalEnum global_test(GlobalEnum e) { return e; }
|
||||
static GlobalEnum global_test(GlobalEnum e) { return e; }
|
||||
|
||||
class A {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -12,6 +12,17 @@
|
|||
/* Type registration */
|
||||
%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*/
|
||||
%insert(runtime) "ocaml.swg"
|
||||
/*#endif*/
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ static File *f_mlout = 0;
|
|||
static File *f_mliout = 0;
|
||||
static File *f_mlbody = 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_value = 0;
|
||||
static File *f_class_ctors = 0;
|
||||
|
|
@ -225,6 +227,8 @@ public:
|
|||
init_func_def = NewString("");
|
||||
f_mlbody = NewString("");
|
||||
f_mlibody = NewString("");
|
||||
f_mltail = NewString("");
|
||||
f_mlitail = NewString("");
|
||||
f_class_ctors = NewString("");
|
||||
f_class_ctors_end = NewString("");
|
||||
f_enum_to_int = NewString("");
|
||||
|
|
@ -244,6 +248,8 @@ public:
|
|||
Swig_register_filebyname("runtime",f_runtime);
|
||||
Swig_register_filebyname("mli",f_mlibody);
|
||||
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_h",f_directors_h);
|
||||
Swig_register_filebyname("classtemplate",f_classtemplate);
|
||||
|
|
@ -265,7 +271,7 @@ public:
|
|||
" (let y = _y in match (x : c_enum_type) with\n"
|
||||
" `unknown -> "
|
||||
" (match (Obj.magic y) with\n"
|
||||
" `Int x -> C_int x\n"
|
||||
" `Int x -> Swig.C_int x\n"
|
||||
" | _ -> raise (LabelNotFromThisEnum v))\n" );
|
||||
|
||||
Printf( f_int_to_enum,
|
||||
|
|
@ -305,11 +311,11 @@ public:
|
|||
Language::top(n);
|
||||
|
||||
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",
|
||||
module );
|
||||
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,
|
||||
"let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n",
|
||||
|
|
@ -351,12 +357,14 @@ public:
|
|||
Delete(f_enum_to_int);
|
||||
Dump(f_class_ctors,f_mlout);
|
||||
Dump(f_class_ctors_end,f_mlout);
|
||||
Dump(f_mltail,f_mlout);
|
||||
Close(f_mlout);
|
||||
Delete(f_mlout);
|
||||
|
||||
Dump(f_enumtypes_type,f_mliout);
|
||||
Dump(f_enumtypes_value,f_mliout);
|
||||
Dump(f_mlibody,f_mliout);
|
||||
Dump(f_mlitail,f_mliout);
|
||||
Close(f_mliout);
|
||||
Delete(f_mliout);
|
||||
|
||||
|
|
@ -894,21 +902,21 @@ public:
|
|||
|
||||
if( Getattr( n, "feature:immutable" ) ) {
|
||||
Printf( f_mlbody,
|
||||
"external _%s : c_obj -> c_obj = \"%s\" \n",
|
||||
"external _%s : Swig.c_obj -> Swig.c_obj = \"%s\" \n",
|
||||
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 ) {
|
||||
Printf( f_enum_to_int,
|
||||
" | `%s -> _%s C_void\n",
|
||||
" | `%s -> _%s Swig.C_void\n",
|
||||
mname, mname );
|
||||
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 );
|
||||
}
|
||||
} 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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
@ -1182,7 +1190,7 @@ public:
|
|||
|
||||
/* Insert sizeof operator for concrete classes */
|
||||
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);
|
||||
}
|
||||
/* Handle up-casts in a nice way */
|
||||
|
|
@ -1421,7 +1429,7 @@ public:
|
|||
if( const_enum ) {
|
||||
Printf( f_int_to_enum, "`Int y)\n" );
|
||||
Printf( f_enum_to_int,
|
||||
"| `Int x -> C_int x\n"
|
||||
"| `Int x -> Swig.C_int x\n"
|
||||
"| _ -> raise (LabelNotFromThisEnum v))\n" );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue