summaryrefslogtreecommitdiff
path: root/Doc/Manual/Ocaml.html
blob: aa6679f9aa6176ea57e5133946de8d8cc70c765f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>SWIG and Ocaml</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
  <body bgcolor="#ffffff">
          <a name="n1"></a>         
<H1><a name="Ocaml"></a>31 SWIG and Ocaml</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Ocaml_nn2">Preliminaries</a>
<ul>
<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="#Ocaml_nn8">The low-level Ocaml/C interface</a>
<ul>
<li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#Ocaml_nn10">Enums</a>
<ul>
<li><a href="#Ocaml_nn11">Enum typing in Ocaml</a>
</ul>
<li><a href="#Ocaml_nn12">Arrays</a>
<ul>
<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_nn17">C++ Classes</a>
<ul>
<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_nn22">Director Classes</a>
<ul>
<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_nn31">Exceptions</a>
</ul>
</ul>
</div>
<!-- INDEX -->



<p>
                This chapter describes SWIG's
support of Ocaml.  Ocaml     is a relatively recent addition to the ML family,
and is a recent   addition     to SWIG.  It's the second compiled, typed
language to be added.    Ocaml   has  widely acknowledged benefits for engineers,
mostly derived  from  a sophisticated    type system, compile-time checking
which eliminates  several  classes of  common  programming errors, and good
native performance.   While  all of this  is wonderful,  there are well-written
C and C++ libraries  that  Ocaml users  will want to  take advantage of as
part of their arsenal  (such  as SSL and  gdbm), as well  as their own mature
C and C++ code.  SWIG  allows   this code  to be used in  a natural, type-safe
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>
If you're not familiar with the Objective Caml language, you can visit
<a href="http://www.ocaml.org/">The Ocaml Website</a>.
</p>

<H2><a name="Ocaml_nn2"></a>31.1 Preliminaries</H2>


<p>
                  SWIG 1.3 works with Ocaml 3.04 and above.  Given the choice,
   you  should  use the latest stable release.  The SWIG Ocaml module has
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
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.
 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 
<a
 href="http://download.camlcity.org/download/">Dl package 
</a>.  The ocaml_dynamic and ocaml_dynamic_cpp targets in the
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.
</p>

<H3><a name="Ocaml_nn3"></a>31.1.1 Running SWIG</H3>


<p>
                  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
 here.   To  build  an Ocaml module, run SWIG using the <tt>-ocaml</tt>
option. 
</p>

<div class="code">                                    
  <pre>
%swig -ocaml example.i
  </pre>
</div>
                         
<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,
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
the resulting .ml and .mli files as well, and do the final link with -custom
(not needed for native link). </p>
               
<H3><a name="Ocaml_nn4"></a>31.1.2 Compiling the code</H3>


<p>
The OCaml 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
easier data sharing between modules if two or more are combined, because
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
the user more freedom with respect to custom typing.

                  Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
 SWIG   interface   like:             
</p>
                       
<div class="code">                                    
  <pre>
% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml
% ocamlc -c swig.mli ; ocamlc -c swig.ml
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
% ocamlc -c example.mli
% ocamlc -c example.ml
  </pre>
</div>
                         
<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>
                       
<div class="code">                                    
  <pre>
% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br>
  </pre>
</div>

<H3><a name="Ocaml_nn5"></a>31.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.  Its 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" 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 -&gt; method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td>
object <i>'binop</i> argument as in<br>
a '+= b</td>
<td>
(invoke object) "+=" argument as in<br>
(invoke a) "+=" b<td></tr>
<tr><th colspan=2>Note that because camlp4 always recognizes &lt;&lt; 
and &gt;&gt;, they are replaced by lsl and lsr in operator names.
<tr><td>
<i>'unop</i> object as in<br>
'! a
</td><td>
(invoke a) "!" C_void</td></tr>
<tr><td>
<b>Smart pointer access like this</b><br>
object '-&gt; method ( args )<br>
</td><td>
(invoke (invoke object "-&gt;" C_void))
</td></tr>
<tr><td>
<b>Invoke syntax</b><br>
object . '( ... )
</td><td>
(invoke object) "()" (C_list [ ... ])
</td></tr>
<tr><td>
<b>Array syntax</b><br>
object '[ 10 ]
</td><td>
(invoke object) "[]" (C_int 10)
</td></tr>
<tr><td>
<b>Assignment syntax</b><br>
let a = '10 and b = '"foo" and c = '1.0 and d = 'true
</td><td>
let a = C_int 10 and b = C_string "foo" and c = C_double 1.0 and d = C_bool true
</td></tr>
<tr><td>
<b>Cast syntax</b><br>
let a = _atoi '("2") as int<br>
let b = (getenv "PATH") to string<br>
This works for int, string, float, bool
</td><td>
let a = get_int (_atoi (C_string "2"))<br>
let b = C_string (getenv "PATH")
</td></tr>
</table>

<H3><a name="Ocaml_nn6"></a>31.1.4 Using your module</H3>


<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
      option to build your functions into the primitive list. This
      option is not needed when you build native code.
</p>

<H3><a name="Ocaml_nn7"></a>31.1.5 Compilation problems and compiling with C++</H3>


<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>

<H2><a name="Ocaml_nn8"></a>31.2 The low-level Ocaml/C interface</H2>


<p>
In order to provide access to overloaded functions, and
provide sensible outputs from them, all C entities 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>
                 
<div class="code"><pre>
type c_obj =
    C_void
  | C_bool of bool
  | C_char of char
  | C_uchar of char
  | C_short of int
  | C_ushort of int
  | C_int of int
  | C_uint of int32
  | C_int32 of int32
  | C_int64 of int64
  | C_float of float
  | C_double of float
  | C_ptr of int64 * int64
  | C_array of c_obj array
  | C_list of c_obj list
  | C_obj of (string -&gt; c_obj -&gt; c_obj)
  | C_string of string
  | C_enum of c_enum_t
</pre></div>

<p>
        A few functions exist which generate and return these:
</p>
               
<ul>
          <li>caml_ptr_val receives a c_obj and returns a void *. &nbsp;This
  should   be used for all pointer purposes.</li>
          <li>caml_long_val receives a c_obj and returns a long. &nbsp;This 
 should   be used for most integral purposes.<br>
          </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 
  its  bool value.</li>
          <li>caml_val_(u)?(char|short|int|long|float|double) receives an 
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_len receives a char * and a length and returns
  a  string  value.</li>
          <li>caml_val_obj receives a void * and an object type and returns 
 a  C_obj,  which contains a closure giving method access.</li>
               
</ul>

<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>

<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
    only that item (i.e. [ C_int 3 ] -&gt; C_int 3), and a list
    containing more than one item is wrapped in C_list (i.e. [ C_char
    'a' ; C_char 'b' -&gt; C_list [ C_char 'a' ; C_char b
    ]). &nbsp;This is in order to make return values easier to handle
    when functions have only one return value, such as constructors,
    and operators. &nbsp;In addition, string, pointer, and object
    values are interchangeable with respect to caml_ptr_val, so you can
    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>

    <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 "&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
    ocaml module, as well as the caml_list_* functions.  These functions
    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>

<H3><a name="Ocaml_nn9"></a>31.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>

<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" 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
section.</td></tr>
<tr><td>"runtime"</td><td>This code is inserted near the end of the C wrapper
file.</td></tr>
<tr><td>"mli"</td><td>This code is inserted into the caml interface file.
Special signatures should be inserted here.
</td></tr>
<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
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>
               
<H3><a name="Ocaml_nn10"></a>31.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
provided for ocaml code to produce and consume these values as
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>

<div class="code"><pre>
%module enum_test
%{
enum c_enum_type { a = 1, b, c = 4, d = 8 };
%}
enum c_enum_type { a = 1, b, c = 4, d = 8 };
</pre></div>

<p>               
The output mli contains:
</p>          

<div class="code"><pre>
type c_enum_type = [
  `unknown
| `c_enum_type
]
type c_enum_tag = [
  `int of int
| `a
| `b
| `c
| `d
]
val int_to_enum c_enum_type -&gt; int -&gt; c_obj
val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</pre>
     </div>

<p>
   So it's possible to do this:   
</p>

<div class="code">      
  <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

# open Enum_test ;;
# let x = C_enum `a ;;
val x : Enum_test.c_obj = C_enum `a
# enum_to_int `c_enum_type x ;;
- : Enum_test.c_obj = C_int 1
# int_to_enum `c_enum_type 4 ;;
- : Enum_test.c_obj = C_enum `c
</pre>
  </div>

<H4><a name="Ocaml_nn11"></a>31.2.2.1 Enum typing in Ocaml</H4>


<p>
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.
</p>

<H3><a name="Ocaml_nn12"></a>31.2.3 Arrays</H3>


<H4><a name="Ocaml_nn13"></a>31.2.3.1 Simple types of bounded arrays</H4>


<p>
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
create typemaps for array types fairly easily. 
</p>

<p>
<tt>%make_simple_array_typemap</tt> is the easiest way to get access to
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_nn14"></a>31.2.3.2 Complex and unbounded arrays</H4>


<p>
Unfortunately, unbounded arrays and pointers can't be handled in a
completely general way by SWIG, because the end-condition of such an
array can't be predicted.  In some cases, it will be by consent
(e.g. an array of four or more chars), sometimes by explicit length
(char *buffer, int len), and sometimes by sentinel value (0,-1,etc.).
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_nn15"></a>31.2.3.3 Using an object</H4>


<p>
It's possible to use C++ to your advantage by creating a simple object that
provides access to your array.  This may be more desirable in some cases,
since the object can provide bounds checking, etc., that prevents crashes.
</p>

<p>
Consider writing an object when the ending condition of your array is complex,
such as using a required sentinel, etc.
</p>

<H4><a name="Ocaml_nn16"></a>31.2.3.4 Example typemap for a function taking float * and int</H4>


<p>
This is a simple example <tt>in</tt> typemap for an array of float, where the
length of the array is specified as an extra parameter.  Other such typemaps
will work similarly.  In the example, the function printfloats is called with
a float array, and specified length.  The actual length reported in the len
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" summary="float * and int typemap example">
<tr><th><center>tarray.i</center></th></tr>
<tr><td><pre>
%module tarray
%{
#include &lt;stdio.h&gt;

void printfloats( float *tab, int len ) {
	int i;

	for( i = 0; i &lt; len; i++ ) {
		printf( "%f ", tab[i] );
	}

	printf( "\n" );  
}
%}

%typemap(in) (float *tab, int len) {
    int i;
    /* $*1_type */
    $2 = caml_array_len($input);
    $1 = ($*1_type *)malloc( $2 * sizeof( float ) );
    for( i = 0; i &lt; $2; i++ ) {
        $1[i] = caml_double_val(caml_array_nth($input,i));
    }
}

void printfloats( float *tab, int len );
</pre></td></tr>
<tr><th>Sample Run</th></tr>
<tr><td><pre>
# open Tarray ;;
# _printfloats (C_array [| C_double 1.0 ; C_double 3.0 ; C_double 5.6666 |]) ;;
1.000000 3.000000 5.666600
- : Tarray.c_obj = C_void
</pre></td></tr></table>


<H3><a name="Ocaml_nn17"></a>31.2.4 C++ Classes</H3>


<p>
C++ classes, along with structs and unions are represented by C_obj
(string -&gt; c_obj -&gt; c_obj) wrapped closures. &nbsp;These objects
contain a method list, and a type, which allow them to be used like
C++ objects.  When passed into typemaps that use pointers, they
degrade to pointers through their "&amp;" method. &nbsp;Every method
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))
</p>

<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>
<tr><td>"sizeof"</td><td>If enabled with ("sizeof"="1") on the module node,
return the object's size in char.</td></tr>
<tr><td>":methods"</td><td>Returns a list of strings containing the names of
the methods this object contains</td></tr>
<tr><td>":classof"</td><td>Returns the name of the class this object belongs 
to.</td></tr>
<tr><td>":parents"</td><td>Returns a list of all direct parent classes which
have been wrapped by SWIG.</td></tr>
<tr><td>"::[parent-class]"</td><td>Returns a view of the object as the
indicated parent class.  This is mainly used internally by the SWIG module,
but may be useful to client programs.</td></tr>
<tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a
method with an optional parameter.  
Called with one argument, the member variable is set to the value of the 
argument.  With zero arguments, the value is returned.
</td></tr>
</table>

<p>
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>

<H4><a name="Ocaml_nn18"></a>31.2.4.1 STL vector and string Example</H4>


<p>
Standard typemaps are now provided for STL vector and string.  More are in
the works.  STL strings are passed just like normal strings, and returned
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.
</p>

<table border="1" bgcolor="#dddddd" summary="STL vector and string example">
<tr><th><center>example.i</center></th></tr>
<tr><td><pre>
%module example
%{
#include "example.h"
%}

%include &lt;stl.i&gt;

namespace std {
        %template(StringVector) std::vector &lt; string &gt;;
};

%include "example.h"
</pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</i></font></td></tr>
</table>

<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>

<div class="code"><pre>
bash-2.05a$ ./example_top 
        Objective Caml version 3.06

        Camlp4 Parsing version 3.06

# open Swig ;;
# open Example ;;
# let x = new_StringVector '() ;;
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 "&amp;"; C_string ":parents"; C_string ":classof";
  C_string ":methods"]
# x -&gt; push_back ("foo") ;;
- : Example.c_obj = C_void
# x -&gt; push_back ("bar") ;;
- : Example.c_obj = C_void
# x -&gt; push_back ("baz") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "bar"
# x -&gt; set (1,"spam") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "spam"
# for i = 0 to (x -&gt; size() as int) - 1 do 
    print_endline ((x '[i to int]) as string) 
  done ;;
foo
bar
baz
- : unit = ()
# 
</pre></div>

<H4><a name="Ocaml_nn19"></a>31.2.4.2 C++ Class Example</H4>


<p>
Here's a simple example using Trolltech's Qt Library:
</p>

<table border="1" bgcolor="#dddddd" summary="Qt Library example">
  <tr><th><center>qt.i</center></th></tr>
<tr><td><pre>
%module qt
%{
#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;
%}
class QApplication {
public:
        QApplication( int argc, char **argv );
        void setMainWidget( QWidget *widget );
        void exec();
};

class QPushButton {
public:
        QPushButton( char *str, QWidget *w );
        void resize( int x, int y );
        void show();
};
</pre></td></tr></table>

<H4><a name="Ocaml_nn20"></a>31.2.4.3 Compiling the example</H4>


<div class="code"><pre>
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$ 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$ swig -ocaml -c++ -I$QTPATH/include  qt.i
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 qt.mli
bash-2.05a$ ocamlc -c qt.ml
bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
  camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \
  -L$QTPATH/lib -cclib -lqt
</pre></div>

<H4><a name="Ocaml_nn21"></a>31.2.4.4 Sample Session</H4>


<div class="code"><pre>
bash-2.05a$ ./qt_top 
        Objective Caml version 3.06

        Camlp4 Parsing version 3.06

# open Swig ;;
# open Qt ;;
# let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj &lt;fun&gt;
# let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj &lt;fun&gt;
# hello -&gt; resize (100,30) ;;
- : Qt.c_obj = C_void
# hello -&gt; show () ;;
- : Qt.c_obj = C_void
# a -&gt; exec () ;;
</pre></div>

<p>
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_nn22"></a>31.2.5 Director Classes</H3>


<H4><a name="Ocaml_nn23"></a>31.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:
</p>

<div class="code"><pre>
%module(directors="1")

...

// Turn on the director class for a specific class like this:
%feature("director")
class foo {
  ...
};
</pre></div>

<H4><a name="Ocaml_nn24"></a>31.2.5.2 Overriding Methods in Ocaml</H4>


<p>
Because the Ocaml language module treats C++ method calls as calls to a
certain function, all you need to do is to define the function that will
handle the method calls in terms of the public methods of the object, and
any other relevant information.  The function <tt>new_derived_object</tt>
uses a stub class to call your methods in place of the ones provided by the
underlying implementation.  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>

<H4><a name="Ocaml_nn25"></a>31.2.5.3 Director Usage Example</H4>


<table border="1" bgcolor="#dddddd" summary="Director usage example">
<tr><th><center>example_prog.ml</center>
</th></tr>
<tr><td><pre>
open Swig
open Example

...

let triangle_class pts ob meth args =
  match meth with
      "cover" -&gt;
        (match args with
             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
           | _ -&gt; raise (Failure "cover needs two double arguments."))
    | _ -&gt; (invoke ob) meth args ;;

let triangle =
  new_derived_object 
    new_shape
    (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
    '() ;;

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.
This is a lot like the class definitions emitted by SWIG, if you look at
example.ml, which is generated when SWIG consumes example.i.  Basically,
you are given the arguments as a c_obj and the method name as a string, and
you must intercept the method you are interested in and provide whatever
return value you need.  Bear in mind that the underlying C++ code needs the
right return type, or an exception will be thrown.  This exception will
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 ( ) 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>

<H4><a name="Ocaml_nn26"></a>31.2.5.4 Creating director objects</H4>


<p>
The definition of the actual object triangle can be described this way:
</p>

<div class="code"><pre>
let triangle =
  new_derived_object 
    new_shape
    (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
    '()
</pre></div>

<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 
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 ]).
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
c_obj provided is the same object that will be returned from new_derived
object, that is, the object exposing the overridden methods.  The other part
is an option ref that will have its value extracted before becoming the
<tt>ob</tt> parameter of your class closure.  This ref will contain
<tt>None</tt> if the C++ object underlying is ever destroyed, and will
consequently trigger an exception when any method is called on the object
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>

<H4><a name="Ocaml_nn27"></a>31.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>


<p>
Special typemaps exist for use with directors, the <tt>directorin, directorout, directorargout</tt>
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>

<H4><a name="Ocaml_nn28"></a>31.2.5.6 <tt>directorin</tt> typemap</H4>


<p>
The <tt>directorin</tt> typemap is used when you will receive arguments from a call
made by C++ code to you, therefore, values will be translated from C++ to
ocaml.  You must provide some valid C_obj value.  This is the value your ocaml
code receives when you are called.  In general, a simple <tt>directorin</tt> typemap
can use the same body as a simple <tt>out</tt> typemap.
</p>

<H4><a name="Ocaml_nn29"></a>31.2.5.7 <tt>directorout</tt> typemap</H4>


<p>
The <tt>directorout</tt> typemap is used when you will send an argument from your
code back to the C++ caller.  That is; directorout specifies a function return
conversion.  You can usually use the same body as an <tt>in</tt> typemap
for the same type, except when there are special requirements for object
ownership, etc.
</p>

<H4><a name="Ocaml_nn30"></a>31.2.5.8 <tt>directorargout</tt> typemap</H4>


<p>
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
values to be put into the output parameters.  The SWIG ocaml module is a bit
loose in order to make code easier to write.  In this case, your return to
the caller must be a list containing the normal function return first, followed
by any argout values in order.  These argout values will be taken from the
list and assigned to the values to be returned to C++ through directorargout typemaps.
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_nn31"></a>31.2.6 Exceptions</H3>


<p>
Catching exceptions is now supported using SWIG's %exception feature.  A simple
but not too useful example is provided by the throw_exception testcase in
Examples/test-suite.  You can provide your own exceptions, too.
</p>

</body>
</html>