1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <!-- Hand-written HTML -->
5 <title>SWIG and Allegro Common Lisp</title>
6 <link rel="stylesheet" type="text/css" href="style.css">
9 <body bgcolor="#ffffff">
11 <H1><a name="Allegrocl_nn1"></a>17 SWIG and Allegro Common Lisp</H1>
13 <div class="sectiontoc">
15 <li><a href="#Allegrocl_nn2">Basics</a>
17 <li><a href="#Allegrocl_nn3">Running Swig</a>
18 <li><a href="#Allegrocl_nn4">Command Line Options</a>
19 <li><a href="#Allegrocl_nn5">Inserting user code into generated files</a>
21 <li><a href="#Allegrocl_nn6">Wrapping Overview</a>
23 <li><a href="#Allegrocl_nn7">Function Wrapping</a>
24 <li><a href="#Allegrocl_nn8">Foreign Wrappers</a>
25 <li><a href="#Allegrocl_nn9">FFI Wrappers</a>
26 <li><a href="#Allegrocl_nn10">Non-overloaded Defuns</a>
27 <li><a href="#Allegrocl_nn11">Overloaded Defuns</a>
28 <li><a href="#Allegrocl_nn12">What about constant and variable access?</a>
29 <li><a href="#Allegrocl_nn13">Object Wrapping</a>
31 <li><a href="#Allegrocl_nn14">Wrapping Details</a>
33 <li><a href="#Allegrocl_nn15">Namespaces</a>
34 <li><a href="#Allegrocl_nn16">Constants</a>
35 <li><a href="#Allegrocl_nn17">Variables</a>
36 <li><a href="#Allegrocl_nn18">Enumerations</a>
37 <li><a href="#Allegrocl_nn19">Arrays</a>
38 <li><a href="#Allegrocl_nn20">Classes and Structs and Unions (oh my!)</a>
40 <li><a href="#Allegrocl_nn21">CLOS wrapping of</a>
41 <li><a href="#Allegrocl_nn22">CLOS Inheritance</a>
42 <li><a href="#Allegrocl_nn23">Member fields and functions</a>
43 <li><a href="#Allegrocl_nn24">Why not directly access C++ classes using foreign types?</a>
45 <li><a href="#Allegrocl_nn25">Templates</a>
47 <li><a href="#Allegrocl_nn26">Generating wrapper code for templates</a>
48 <li><a href="#Allegrocl_nn27">Implicit Template instantiation</a>
50 <li><a href="#Allegrocl_nn28">Typedef, Templates, and Synonym Types</a>
52 <li><a href="#Allegrocl_nn29">Choosing a primary type</a>
54 <li><a href="#Allegrocl_nn30">Function overloading/Parameter defaulting</a>
55 <li><a href="#Allegrocl_nn31">Operator wrapping and Operator overloading</a>
56 <li><a href="#Allegrocl_nn32">Varargs</a>
57 <li><a href="#Allegrocl_nn33">C++ Exceptions</a>
58 <li><a href="#Allegrocl_nn34">Pass by value, pass by reference</a>
60 <li><a href="#Allegrocl_nn35">Typemaps</a>
62 <li><a href="#Allegrocl_nn36">Code Generation in the C++ Wrapper</a>
64 <li><a href="#Allegrocl_nn37">IN Typemap</a>
65 <li><a href="#Allegrocl_nn38">OUT Typemap</a>
66 <li><a href="#Allegrocl_nn39">CTYPE Typemap</a>
68 <li><a href="#Allegrocl_nn40">Code generation in Lisp wrappers</a>
70 <li><a href="#Allegrocl_nn41">LIN Typemap</a>
71 <li><a href="#Allegrocl_nn42">LOUT Typemap</a>
72 <li><a href="#Allegrocl_nn43">FFITYPE Typemap</a>
73 <li><a href="#Allegrocl_nn44">LISPTYPE Typemap</a>
74 <li><a href="#Allegrocl_nn45">LISPCLASS Typemap</a>
76 <li><a href="#Allegrocl_nn46">Modifying SWIG behavior using typemaps</a>
78 <li><a href="#Allegrocl_nn47">Identifier Converter functions</a>
80 <li><a href="#Allegrocl_nn48">Creating symbols in the lisp environment</a>
81 <li><a href="#Allegrocl_nn49">Existing identifier-converter functions</a>
83 <li><a href="#Allegrocl_nn50">identifier-convert-null</a>
84 <li><a href="#Allegrocl_nn51">identifier-convert-lispify</a>
85 <li><a href="#Allegrocl_nn52">Default identifier to symbol conversions</a>
87 <li><a href="#Allegrocl_nn53">Defining your own identifier-converter</a>
88 <li><a href="#Allegrocl_nn54">Instructing SWIG to use a particular identifier-converter</a>
97 This chapter describes SWIG's support of Allegro Common Lisp. Allegro
98 CL is a full-featured implementation of the Common Lisp language
99 standard that includes many vendor-specific enhancements and add-on
100 modules for increased usability.
104 One such module included in Allegro CL is the Foreign Functions
105 Interface (FFI). This module, tailored primarily toward interfacing
106 with C/C++ and, historically, Fortran, provides a means by which
107 compiled foreign code can be loaded into a running lisp
108 environment and executed. The interface supports the calling of
109 foreign functions and methods, allows for executing lisp routines
110 from foreign code (callbacks), and the passing of data between foreign
115 The goal of this module is to make it possible to quickly generate the
116 necessary foreign function definitions so one can make use of C/C++
117 foreign libraries directly from lisp without the tedium of having to
118 code them by hand. When necessary, it will also generate further C/C++
119 code that will need to be linked with the intended library for proper
120 interfacing from lisp. It has been designed with an eye toward
121 flexibility. Some foreign function calls may release the heap, while
122 other should not. Some foreign functions should automatically convert
123 lisp strings into native strings, while others should not. These
124 adjustments and many more are possible with the current module.
128 It is significant to note that, while this is a vendor-specific
129 module, we would like to acknowledge the current and ongoing
130 work by developers in the open source lisp community that are
131 working on similar interfaces to implementation-independent
132 foreign function interfaces (UFFI or CFFI, for example). Such
133 work can only benefit the lisp community, and we would not
134 be unhappy to see some enterprising folk use this work to add
138 <H2><a name="Allegrocl_nn2"></a>17.1 Basics</H2>
141 <H3><a name="Allegrocl_nn3"></a>17.1.1 Running Swig</H3>
145 If you're reading this, you must have some library you need to
146 generate an interface for. In order for SWIG to do this work, however,
147 it needs a bit of information about how it should go about creating
148 your interface, and what you are interfacing to.
152 SWIG expects a description of what in the foreign interface you wish
153 to connect to. It must consisting of C/C++ declarations and special
154 SWIG directives. SWIG can be furnished with a header file, but an
155 interface can also be generated without library headers by supplying a
156 simple text file--called the interface file, which is typically named
157 with a <tt>.i</tt> extension--containing any foreign declarations of
158 identifiers you wish to use. The most common approach is to use a an
159 interface file with directives to parse the needed headers. A straight
160 parse of library headers will result in usable code, but SWIG
161 directives provides much freedom in how a user might tailor the
162 generated code to their needs or style of coding.
166 Note that SWIG does not require any function definitions; the
167 declarations of those functions is all that is necessary. Be careful
168 when tuning the interface as it is quite possible to generate code
169 that will not load or compile.
173 An example interface file is shown below. It makes use of two SWIG
174 directives, one of which requests that the declarations in a header
175 file be used to generate part of the interface, and also includes an
176 additional declaration to be added.</p>
178 <div class="code">example.i
188 <p>The contents of header.h are very simple:</p>
189 <div class="code">header.h
191 int fact(char *statement); // pass it a fact, and it will rate it.
195 <p>The contents of example.cl will look like this:</p>
197 <div class="targetlang">example.cl
200 (:use :common-lisp :swig :ff :excl))
202 ... helper routines for defining the interface ...
207 ((PARM0_statement cl:string (* :char) ))
210 (let ((SWIG_arg0 PARM0_statement))
211 (swig-ff-call SWIG_arg0)))
214 ((PARM0_n cl:integer :int ))
217 (let ((SWIG_arg0 PARM0_n))
218 (swig-ff-call SWIG_arg0)))
220 (swig-dispatcher ("fact" :type :function :arities (1)))
225 The generated file contains calls to internal swig helper
226 functions. In this case there are two calls to swig-defun.
227 These calls will expand into code that will make the appropriate
228 definitions using the Allegro FFI. Note also, that this code is
229 <b>erroneous</b>. Function overloading is not supported in C, and this
230 code will not compile even though SWIG did not complain.
234 In order to generate a C interface to Allegro CL using this code run
235 swig using the <tt>-allegrocl</tt> option, as below:
240 % swig -allegrocl example.i
245 When building an interface to C++ code, include the <tt>-c++</tt> option:
250 % swig -allegrocl -c++ example.i
255 As a result of running one of the above commands, a file named <tt>example.cl</tt>
256 will be generated containing the lisp side of the interface. As well, a file
257 <tt>example_wrap.cxx</tt> is also generated, containing C/C++ wrapper code to
258 facilitate access to C++ methods, enumeration values, and constant values.
259 Wrapper functions are necessary in C++ due to the lack of a standard for mangling
260 the names of symbols across all C++ compilers. These wrapper functions are
261 exported from the shared library as appropriate, using the C name mangling
262 convention. The lisp code that is generated will interface to your foreign
263 library through these wrappers.
267 It is possible to disable the creation of the .cxx file when generating a C
268 interface by using the -nocwrap command-line argument. For interfaces that
269 don't contain complex enum or constant expressions, contain nested struct/union
270 declarations, or doesn't need to use many of the SWIG customization featuers,
271 this will result in a more streamlined, direct interface to the
276 The generated wrapper file is below. It contains very simple
277 wrappers by default, that simply pass the arguments to the
281 <div class="code">example_wrap.i
283 ... lots of SWIG internals ...
285 EXPORT int ACL___fact__SWIG_0 (char *larg1) {
286 int lresult = (int)0 ;
287 char *arg1 = (char *) 0 ;
292 result = (int)fact(arg1);
302 EXPORT int ACL___fact__SWIG_1 (int larg1) {
303 int lresult = (int)0 ;
309 result = (int)fact(arg1);
321 And again, the generated lisp code. Note that it differs from
322 what is generated when parsing C code:
325 <div class="targetlang">
331 (swig-defmethod ("fact" "ACL___fact__SWIG_0" :type :function :arity 1)
332 ((PARM0_statement cl:string (* :char) ))
335 (let ((SWIG_arg0 PARM0_statement))
336 (swig-ff-call SWIG_arg0)))
338 (swig-defmethod ("fact" "ACL___fact__SWIG_1" :type :function :arity 1)
339 ((PARM0_n cl:integer :int ))
342 (let ((SWIG_arg0 PARM0_n))
343 (swig-ff-call SWIG_arg0)))
345 (swig-dispatcher ("fact" :type :function :arities (1)))
349 <p>In this case, the interface generates two swig-defmethod forms and
350 a swig-dispatcher form. This provides a single functional interface for
351 all overloaded routines. A more detailed description of this features
352 is to be found in the section titled <b>Function overloading/Parameter defaulting</b>.
355 In order to load a C++ interface, you will need to build a shared library
356 from example_wrap.cxx. Be sure to link in the actual library you created
357 the interface for, as well as any other dependent shared libraries. For
358 example, if you intend to be able to call back into lisp, you will also
359 need to link in the Allegro shared library. The library you create from
360 the C++ wrapper will be what you then load into Allegro CL.
363 <H3><a name="Allegrocl_nn4"></a>17.1.2 Command Line Options</H3>
367 There are three Allegro CL specific command-line option:
372 swig -allegrocl [ options ] filename
374 -identifier-converter [name] - Binds the variable swig:*swig-identifier-convert*
375 in the generated .cl file to <tt>name</tt>.
376 This function is used to generate symbols
377 for the lisp side of the interface.
379 -cwrap - [default] Generate a .cxx file containing C wrapper function when
380 wrapping C code. The interface generated is similar to what is
382 -nocwrap - Explicitly turn off generation of .cxx wrappers for C code. Reasonable
383 for modules with simple interfaces. Can not handle all legal enum
384 and constant constructs, or take advantage of SWIG customization features.
386 -isolate - With this command-line argument, all lisp helper functions are defined
387 in a unique package named <tt>swig.<module-name></tt> rather than
388 <tt>swig</tt>. This prevents conflicts when the module is
389 intended to be used with other swig generated interfaces that may,
390 for instance, make use of different identifier converters.
395 See <a href="#Allegrocl_nn47">Section 17.5 Identifier converter
396 functions</a> for more details.
399 <H3><a name="Allegrocl_nn5"></a>17.1.3 Inserting user code into generated files</H3>
403 It is often necessary to include user-defined code into the
404 automatically generated interface files. For example, when building
405 a C++ interface, example_wrap.cxx will likely not compile unless
406 you add a <tt>#include "header.h"</tt> directive. This can be done
407 using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
425 Additional sections have been added for inserting into the
426 generated lisp interface file
429 <li><tt>lisphead</tt> - inserts before type declarations</li>
430 <li><tt>lisp</tt> - inserts after type declarations according to
431 where it appears in the .i file</li>
434 Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
435 <tt>%insert("header") %{ ... %}</tt>.
439 <H2><a name="Allegrocl_nn6"></a>17.2 Wrapping Overview</H2>
443 New users to SWIG are encouraged to read
444 <a href="SWIG.html#SWIG">SWIG Basics</a>, and
445 <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>, for those
446 interested in generating an interface to C++.
449 <H3><a name="Allegrocl_nn7"></a>17.2.1 Function Wrapping</H3>
453 Writing lisp code that directly invokes functions at the foreign
454 function interface level can be cumbersome. Data must often be
455 translated between lisp and foreign types, data extracted from
456 objects, foreign objects allocated and freed upon completion of
457 the foreign call. Dealing with pointers can be unwieldy when it
458 comes to keeping them distinct from other valid integer values.
462 We make an attempt to ease some of these burdens by making the
463 interface to foreign code much more lisp-like, rather than C
464 like. How this is done is described in later chapters. The
465 layers themselves, appear as follows:
468 <div class="diagram">
472 | Foreign Code | What we're generating an interface to.
478 | Wrapper code | extern "C" wrappers calling C++
479 |______________| functions and methods.
481 . . . - - + - - . . .
484 | FFI Layer | Low level lisp interface. ff:def-foreign-call,
485 |______________| ff:def-foreign-variable
487 +----------------------------
488 _______v______ _______v______
490 | Defuns | | Defmethods | wrapper for overloaded
491 |______________| |______________| functions or those with
492 (lisp side) | defaulted arguments
493 Wrapper for non-overloaded |
494 functions and methods _______v______
496 | Defuns | dispatch function
497 |______________| to overloads based
502 <H3><a name="Allegrocl_nn8"></a>17.2.2 Foreign Wrappers</H3>
506 These wrappers are as generated by SWIG default. The types of
507 function parameters can be transformed in place using the CTYPE
508 typemap. This is use for converting pass-by-value parameters to
509 pass-by-reference where necessary. All wrapper parameters are then
510 bound to local variables for possible transformation of values
511 (see LIN typemap). Return values can be transformed via the OUT
515 <H3><a name="Allegrocl_nn9"></a>17.2.3 FFI Wrappers</H3>
519 These are the generated ff:def-foreign-call forms. No typemaps are
520 applicable to this layer, but the <tt>%ffargs</tt> directive is
521 available for use in .i files, to specify which keyword arguments
522 should be specified for a given function.
525 <div class="code">ffargs.i:
529 %ffargs(strings_convert="nil",call_direct="t") foo;
530 %ffargs(strings_convert="nil",release_heap=":never",optimize_for_space="t") bar;
532 int foo(float f1, float f2);
533 int foo(float f1, char c2);
535 void bar(void *lisp_fn);
543 <div class="targetlang">ffargs.cl:
547 (swig-defmethod ("foo" "ACL___foo__SWIG_0" :type :function :arity 2)
548 ((PARM0_f1 cl:single-float :float )
549 (PARM1_f2 cl:single-float :float ))
552 :strings-convert nil)
553 (let ((SWIG_arg0 PARM0_f1))
554 (let ((SWIG_arg1 PARM1_f2))
555 (swig-ff-call SWIG_arg0 SWIG_arg1))))
557 (swig-defmethod ("foo" "ACL___foo__SWIG_1" :type :function :arity 2)
558 ((PARM0_f1 cl:single-float :float )
559 (PARM1_c2 cl:character :char character))
562 :strings-convert nil)
563 (let ((SWIG_arg0 PARM0_f1))
564 (let ((SWIG_arg1 PARM1_c2))
565 (swig-ff-call SWIG_arg0 SWIG_arg1))))
567 (swig-dispatcher ("foo" :type :function :arities (2)))
568 (swig-defun ("bar" "ACL___bar__SWIG_0" :type :function)
569 ((PARM0_lisp_fn (* :void) ))
572 :optimize-for-space t
573 :strings-convert nil)
574 (let ((SWIG_arg0 PARM0_lisp_fn))
575 (swig-ff-call SWIG_arg0)))
578 (swig-defun ("xxx" "ACL___xxx__SWIG_0" :type :function)
580 (:returning ((* :char) )
587 <pre>%ffargs(strings_convert="t");</pre>
591 Is the only default value specified in <tt>allegrocl.swg</tt> to force
592 the muffling of warnings about automatic string conversion when defining
593 ff:def-foreign-call's.
596 <H3><a name="Allegrocl_nn10"></a>17.2.4 Non-overloaded Defuns</H3>
600 These are simple defuns. There is no typechecking of arguments.
601 Parameters are bound to local variables for possible
602 transformation of values, such as pulling values out of instance
603 slots or allocating temporary stack allocated structures, via the
604 <tt>lin</tt> typemap. These arguments are then passed to the
605 foreign-call (where typechecking may occur). The return value from
606 this function can be manipulated via the <tt>lout</tt> typemap.
609 <H3><a name="Allegrocl_nn11"></a>17.2.5 Overloaded Defuns</H3>
613 In the case of overloaded functions, mulitple layers are
614 generated. First, all the overloads for a given name are separated
615 out into groups based on arity, and are wrapped in
616 defmethods. Each method calls a distinct wrapper function, but are
617 themselves distinguished by the types of their arguments
618 (see <tt>lispclass</tt> typemap). These are further wrapped in a
619 dispatching function (defun) which will invoke the appropriate
620 generic-function based on arity. This provides a single functional
621 interface to all overloads. The return value from this function
622 can be manipulated via the <tt>lout</tt> typemap.
625 <H3><a name="Allegrocl_nn12"></a>17.2.6 What about constant and variable access?</H3>
629 Along with the described functional layering, when creating a .cxx wrapper,
630 this module will generate getter and--if not immutable--setter,
631 functions for variables and constants. If the -nocwrap option is used,
632 <tt>defconstant</tt> and <tt>ff:def-foreign-variable</tt> forms will be
633 generated for accessing constants and global variables. These, along with
634 the <tt>defuns</tt> listed above are the intended API for calling
635 into the foreign module.
638 <H3><a name="Allegrocl_nn13"></a>17.2.7 Object Wrapping</H3>
642 All non-primitive types (Classes, structs, unions, and typedefs
643 involving same) have a corresponding foreign-type defined on the
644 lisp side via ff:def-foreign-type.
648 All non-primitive types are further represented by a CLOS class,
649 created via defclass. An attempt is made to create the same class
650 hierarchy, with all classes inheriting directly or indirectly from
651 ff:foreign-pointer. Further, wherever it is apparent, all pointers
652 returned from foreign code are wrapped in a CLOS instance of the
653 appropriate class. For ff:def-foreign-calls that have been defined
654 to expect a :foreign-address type as argument, these CLOS instances
655 can legally be passed and the pointer to the C++ object
656 automatically extracted. This is a natural feature of Allegro's
657 foreign function interface.
660 <H2><a name="Allegrocl_nn14"></a>17.3 Wrapping Details</H2>
664 In this section is described how particular C/C++ constructs are
665 translated into lisp.
668 <H3><a name="Allegrocl_nn15"></a>17.3.1 Namespaces</H3>
672 C++ namespaces are translated into Lisp packages by SWIG. The
673 Global namespace is mapped to a package named by the <tt>%module</tt>
674 directive or the <tt>-module</tt> command-line argument. Further
675 namespaces are generated by the <tt>swig-defpackage</tt> utility
676 function and given names based on Allegro CLs nested namespace
677 convention. For example:
680 <div class="code">foo.i:
693 int do_something(int n);
698 <p>Generates the following code.
700 <div class="targetlang">foo.cl
703 (:use :common-lisp :swig :ff :excl))
707 (swig-defpackage ("car"))
708 (swig-defpackage ("car" "tires"))
712 (swig-in-package ("car" "tires"))
713 (swig-defun ("do_something" "ACL_car_tires__do_something__SWIG_0" :type :function)
717 (let ((SWIG_arg0 PARM0_n))
718 (swig-ff-call SWIG_arg0)))
723 The above interface file would cause packages foo, foo.car, and
724 foo.car.tires to be created. One would find the function wrapper
725 for do_something defined in the foo.car.tires package(*).
728 <p>(<b>*</b>) Except for the package named by the module, all
729 namespace names are passed to the identifier-converter-function
730 as strings with a <tt>:type</tt> of <tt>:namespace</tt>. It is the
731 job of this function to generate the desired symbol, accounting for
732 case preferences, additional naming cues, etc.
736 Note that packages created by <tt>swig-defpackage</tt> do not
737 use the COMMON-LISP or EXCL package. This reduces possible
738 conflicts when defining foreign types via the SWIG interface
739 in <b>all but the toplevel modules package</b>. This may
740 lead to confusion if, for example, the current package is
741 <tt>foo.car.tires</tt> and you attempt to use a common-lisp
742 function such as <tt>(car '(1 2 3)</tt>.
745 <H3><a name="Allegrocl_nn16"></a>17.3.2 Constants</H3>
750 Constants, as declared by the preprocessor #define macro or SWIG
751 <tt>%constant</tt> directive, are included in SWIGs parse tree
752 when it can be determined that they are, or could be reduced to,
753 a literal value. Such values are translated into defconstant
754 forms in the generated lisp wrapper when the -nocwrap command-line
755 options is used. Else, wrapper functions are generated as in the
756 case of variable access (see section below).
759 Here are examples of simple preprocessor constants when using -nocwrap.
763 #define A 1 => (swig-defconstant "A" 1)
764 #define B 'c' => (swig-defconstant "B" #\c)
765 #define C B => (swig-defconstant "C" #\c)
766 #define D 1.0e2 => (swig-defconstant "D" 1.0d2)
767 #define E 2222 => (swig-defconstant "E" 2222)
768 #define F (unsigned int)2222 => no code generated
769 #define G 1.02e2f => (swig-defconstant "G" 1.02f2)
770 #define H foo => no code generated
775 Note that where SWIG is unable to determine if a constant is
776 a literal, no node is added to the SWIG parse tree, and so
777 no values can be generated.
781 For preprocessor constants containing expressions which can be
782 reduced to literal values, nodes are created, but with no simplification
783 of the constant value. A very very simple infix to prefix converter
784 has been implemented that tries to do the right thing for simple cases, but
785 does not for more complex expressions. If the literal parser determines
786 that something is wrong, a warning will be generated and the literal
787 expression will be included in the generated code, but commented out.
792 #define I A + E => (swig-defconstant "I" (+ 1 2222))
793 #define J 1|2 => (swig-defconstant "J" (logior 1 2))
794 #define Y 1 + 2 * 3 + 4 => (swig-defconstant "Y" (* (+ 1 2) (+ 3 4)))
795 #define Y1 (1 + 2) * (3 + 4) => (swig-defconstant "Y1" (* (+ 1 2) (+ 3 4)))
796 #define Y2 1 * 2 + 3 * 4 => (swig-defconstant "Y2" (* 1 (+ 2 3) 4)) ;; WRONG
797 #define Y3 (1 * 2) + (3 * 4) => (swig-defconstant "Y3" (* 1 (+ 2 3) 4)) ;; WRONG
798 #define Z 1 + 2 - 3 + 4 * 5 => (swig-defconstant "Z" (* (+ 1 (- 2 3) 4) 5)) ;; WRONG
802 Users are cautioned to get to know their constants before use, or
803 not use the <tt>-nocwrap</tt> command-line option.
806 <H3><a name="Allegrocl_nn17"></a>17.3.3 Variables</H3>
810 For C wrapping, a def-foreign-variable call is generated for access
814 When wrapping C++ code, both global and member variables, getter
815 wrappers are generated for accessing their value, and if not immutable,
816 setter wrappers as well. In the example below, note the lack of a
817 setter wrapper for global_var, defined as const.
820 <div class="code">vars.h
823 int const global_var = 2;
824 float glob_float = 2.0;
832 <div class="targetlang">vars.cl
834 (swig-in-package ("nnn"))
835 (swig-defun ("global_var" "ACL_nnn__global_var_get__SWIG_0" :type :getter)
842 (swig-defun ("glob_float" "ACL_nnn__glob_float_set__SWIG_0" :type :setter)
843 ((PARM0_glob_float :float ))
846 (let ((SWIG_arg0 PARM0_glob_float))
847 (swig-ff-call SWIG_arg0)))
850 (swig-defun ("glob_float" "ACL_nnn__glob_float_get__SWIG_0" :type :getter)
852 (:returning (:float )
859 Note also, that where applicable, setter wrappers are implemented
860 as setf methods on the getter function, providing a lispy interface
864 <div class="targetlang">
866 user> (load "globalvar.dll")
867 ; Foreign loading globalvar.dll.
869 user> (load "globalvar.cl")
870 ; Loading c:\mikel\src\swig\test\globalvar.cl
873 globalvar> (globalvar.nnn::global_var)
875 globalvar> (globalvar.nnn::glob_float)
877 globalvar> (setf (globalvar.nnn::glob_float) 3.0)
879 globalvar> (globalvar.nnn::glob_float)
884 <H3><a name="Allegrocl_nn18"></a>17.3.4 Enumerations</H3>
888 In C, an enumeration value is an integer value, while in C++ an
889 enumeration value is implicitly convertible to an integer value,
890 but can also be distinguished by it's enum type. For each enum
891 declaration a def-foreign-type is generated, assigning the enum
892 a default type of :int. Users may adjust the foreign type of
893 enums via SWIG <tt>typemaps</tt>.
897 Enum values are a bit trickier as they can be initialized using
898 any valid C/C++ expression. In C with the -nocwrap command-line option,
899 we handle the typical cases (simple integer initialization) and
900 generate a defconstant form for each enum value. This has the advantage
901 of it not being necessary to probe into foreign space to retrieve enum
902 values. When generating a .cxx wrapper file, a more general solution is
903 employed. A wrapper variable is created in the module_wrap.cxx file, and
904 a ff:def-foreign-variable call is generated to retrieve it's value into lisp.
907 <p>For example, the following header file
908 <div class="code">enum.h:
910 enum COL { RED, GREEN, BLUE };
911 enum FOO { FOO1 = 10, FOO2, FOO3 };
915 In -nocwrap mode, generates
917 <div class="targetlang">enum.cl:
919 (swig-def-foreign-type "COL" :int)
920 (swig-defconstant "RED" 0)
921 (swig-defconstant "GREEN" (+ #.(swig-insert-id "RED" () :type :constant) 1))
922 (swig-defconstant "BLUE" (+ #.(swig-insert-id "GREEN" () :type :constant) 1))
924 (swig-def-foreign-type "FOO" :int)
925 (swig-defconstant "FOO1" 10)
926 (swig-defconstant "FOO2" (+ #.(swig-insert-id "FOO1" () :type :constant) 1))
927 (swig-defconstant "FOO3" (+ #.(swig-insert-id "FOO2" () :type :constant) 1))
931 <p>And when generating a .cxx wrapper
932 <div class="code">enum_wrap.cxx:
934 EXPORT const int ACL_ENUM___RED__SWIG_0 = RED;
935 EXPORT const int ACL_ENUM___GREEN__SWIG_0 = GREEN;
936 EXPORT const int ACL_ENUM___BLUE__SWIG_0 = BLUE;
937 EXPORT const int ACL_ENUM___FOO1__SWIG_0 = FOO1;
938 EXPORT const int ACL_ENUM___FOO2__SWIG_0 = FOO2;
939 EXPORT const int ACL_ENUM___FOO3__SWIG_0 = FOO3;
945 <div class="targetlang">enum.cl:
947 (swig-def-foreign-type "COL" :int)
948 (swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant)
949 (swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant)
950 (swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant)
952 (swig-def-foreign-type "FOO" :int)
953 (swig-defvar "FOO1" "ACL_ENUM___FOO1__SWIG_0" :type :constant)
954 (swig-defvar "FOO2" "ACL_ENUM___FOO2__SWIG_0" :type :constant)
955 (swig-defvar "FOO3" "ACL_ENUM___FOO3__SWIG_0" :type :constant)
960 <H3><a name="Allegrocl_nn19"></a>17.3.5 Arrays</H3>
964 One limitation in the Allegro CL foreign-types module, is that,
965 without macrology, expressions may not be used to specify the
966 dimensions of an array declaration. This is not a horrible
967 drawback unless it is necessary to allocate foreign structures
968 based on the array declaration using ff:allocate-fobject. When it
969 can be determined that an array bound is a valid numeric value,
970 SWIG will include this in the generated array declaration on the
971 lisp side, otherwise the value will be included, but commented out.
975 Below is a comprehensive example, showing a number of legal
976 C/C++ array declarations and how they are translated
977 into foreign-type specifications in the generated lisp code.
979 <div class="code">array.h
981 #define MAX_BUF_SIZE 1024
985 float global_var2[MAX_BUF_SIZE];
989 enum COLOR { RED = 10, GREEN = 20, BLUE, PURPLE = 50, CYAN };
992 char global_var3[MAX_BUF_SIZE + 1];
993 float global_var4[MAX_BUF_SIZE][13];
994 signed short global_var5[MAX_BUF_SIZE + MAX_BUF_SIZE];
996 int enum_var5[GREEN];
999 COLOR enum_var7[CYAN][MAX_BUF_SIZE];
1008 <div class="targetlang">array.cl
1010 (in-package #.*swig-module-name*)
1012 (swig-defpackage ("FOO"))
1013 (swig-defpackage ("BAR"))
1015 (swig-in-package ())
1016 (swig-def-foreign-type "COLOR" :int)
1017 (swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant)
1018 (swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant)
1019 (swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant)
1020 (swig-defvar "PURPLE" "ACL_ENUM___PURPLE__SWIG_0" :type :constant)
1021 (swig-defvar "CYAN" "ACL_ENUM___CYAN__SWIG_0" :type :constant)
1023 (swig-in-package ())
1025 (swig-defconstant "MAX_BUF_SIZE" 1024)
1026 (swig-in-package ("FOO"))
1028 (swig-defun ("global_var1" "ACL_FOO__global_var1_get__SWIG_0" :type :getter)
1030 (:returning ((* :int) )
1032 (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
1035 (swig-defun ("global_var2" "ACL_FOO__global_var2_set__SWIG_0" :type :setter)
1036 ((global_var2 (:array :float 1024) ))
1037 (:returning (:void )
1039 (let ((SWIG_arg0 global_var2))
1040 (swig-ff-call SWIG_arg0)))
1043 (swig-in-package ())
1044 (swig-in-package ("BAR"))
1045 (swig-defun ("global_var3" "ACL_BAR__global_var3_set__SWIG_0" :type :setter)
1046 ((global_var3 (:array :char #|1024+1|#) ))
1047 (:returning (:void )
1049 (let ((SWIG_arg0 global_var3))
1050 (swig-ff-call SWIG_arg0)))
1053 (swig-defun ("global_var4" "ACL_BAR__global_var4_set__SWIG_0" :type :setter)
1054 ((global_var4 (:array (:array :float 13) 1024) ))
1055 (:returning (:void )
1057 (let ((SWIG_arg0 global_var4))
1058 (swig-ff-call SWIG_arg0)))
1061 (swig-defun ("global_var4" "ACL_BAR__global_var4_get__SWIG_0" :type :getter)
1063 (:returning ((* (:array :float 13)) )
1065 (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
1068 (swig-defun ("global_var5" "ACL_BAR__global_var5_set__SWIG_0" :type :setter)
1069 ((global_var5 (:array :short #|1024+1024|#) ))
1070 (:returning (:void )
1072 (let ((SWIG_arg0 global_var5))
1073 (swig-ff-call SWIG_arg0)))
1076 (swig-defun ("enum_var5" "ACL_BAR__enum_var5_set__SWIG_0" :type :setter)
1077 ((enum_var5 (:array :int #|GREEN|#) ))
1078 (:returning (:void )
1080 (let ((SWIG_arg0 enum_var5))
1081 (swig-ff-call SWIG_arg0)))
1084 (swig-defun ("enum_var6" "ACL_BAR__enum_var6_set__SWIG_0" :type :setter)
1085 ((enum_var6 (:array :int #|CYAN|#) ))
1086 (:returning (:void )
1088 (let ((SWIG_arg0 enum_var6))
1089 (swig-ff-call SWIG_arg0)))
1092 (swig-defun ("enum_var7" "ACL_BAR__enum_var7_set__SWIG_0" :type :setter)
1093 ((enum_var7 (:array (:array #.(swig-insert-id "COLOR" ()) 1024) #|CYAN|#) ))
1094 (:returning (:void )
1096 (let ((SWIG_arg0 enum_var7))
1097 (swig-ff-call SWIG_arg0)))
1100 (swig-defun ("enum_var7" "ACL_BAR__enum_var7_get__SWIG_0" :type :getter)
1102 (:returning ((* (:array #.(swig-insert-id "COLOR" ()) 1024)) )
1104 (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
1108 <H3><a name="Allegrocl_nn20"></a>17.3.6 Classes and Structs and Unions (oh my!)</H3>
1111 <H4><a name="Allegrocl_nn21"></a>17.3.6.1 CLOS wrapping of</H4>
1115 Classes, unions, and structs are all treated the same way by the
1116 interface generator. For any of these objects, a
1117 def-foreign-type and a defclass form are generated. For every
1118 function that returns an object (or pointer/reference) of C/C++
1119 type <tt>X</tt>, the wrapping defun (or defmethod) on the Lisp
1120 side will automatically wrap the pointer returned in an instance
1121 of the apropriate class. This makes it much easier to write and
1122 debug code than if pointers were passed around as a jumble of
1126 <H4><a name="Allegrocl_nn22"></a>17.3.6.2 CLOS Inheritance</H4>
1130 The CLOS class schema generated by the interface mirrors the
1131 inheritance of the classes in foreign code, with the
1132 ff:foreign-pointer class at its root. ff:foreign-pointer is a thin
1133 wrapper for pointers that is made available by the foreign function
1134 interface. It's key benefit is that it may be passed as an argument
1135 to any ff:def-foreign-call that is expecting a pointer as the
1139 <H4><a name="Allegrocl_nn23"></a>17.3.6.3 Member fields and functions</H4>
1143 All public fields will have accessor getter/setter functions
1144 generated for them, as appropriate. All public member functions
1145 will have wrapper functions generated.
1149 We currently ignore anything that isn't <tt>public</tt> (i.e.
1150 <tt>private</tt> or <tt>protected</tt>), because the C++ compiler
1151 won't allow the wrapper functions to access such fields. Likewise,
1152 the interface does nothing for <tt>friend</tt> directives,
1155 <H4><a name="Allegrocl_nn24"></a>17.3.6.4 Why not directly access C++ classes using foreign types?</H4>
1159 The def-foreign-type generated by the SWIG interface is
1160 currently incomplete. We can reliably generate the object layout
1161 of simple structs and unions; they can be allocated via
1162 ff:allocate-fobject, and their member variables accessed
1163 directly using the various ff:fslot-value-* functions. However,
1164 the layout of C++ classes is more complicated. Different
1165 compilers adjust class layout based on inheritance patterns, and
1166 the presence of virtual member functions. The size of member
1167 function pointers vary across compilers as well. As a result, it
1168 is recommended that users of any generated interface not attempt
1169 to access C++ instances via the foreign type system, but instead
1170 use the more robust wrapper functions.
1173 <H3><a name="Allegrocl_nn25"></a>17.3.7 Templates</H3>
1177 <H4><a name="Allegrocl_nn26"></a>17.3.7.1 Generating wrapper code for templates</H4>
1181 SWIG provides support for dealing with templates, but by
1182 default, it will not generate any member variable or function
1183 wrappers for templated classes. In order to create these
1184 wrappers, you need to explicitly tell SWIG to instantiate
1185 them. This is done via the
1186 <a href="SWIGPlus.html#SWIGPlus_nn30"><tt>%template</tt></a>
1190 <H4><a name="Allegrocl_nn27"></a>17.3.7.2 Implicit Template instantiation</H4>
1194 While no wrapper code is generated for accessing member
1195 variables, or calling member functions, type code is generated
1196 to include these templated classes in the foreign-type and CLOS
1200 <H3><a name="Allegrocl_nn28"></a>17.3.8 Typedef, Templates, and Synonym Types</H3>
1204 In C/C++ it is possible, via typedef, to have many names refer to
1205 the same <tt>type</tt>. In general, this is not a problem, though
1206 it can lead to confusion. Assume the below C++ header file:
1209 <div class="code">synonyms.h
1218 A *xxx(int i); /* sets A->x = A->y = i */
1219 Foo *yyy(int i); /* sets Foo->x = Foo->y = i */
1221 int zzz(A *inst = 0); /* return inst->x + inst->y */
1226 The function <tt>zzz</tt> is an overloaded functions; the
1227 foreign function call to it will be wrapped in a
1228 generic-function whose argument will be checked against a type
1229 of <tt>A</tt>. Assuming a simple implementation, a call
1230 to <tt>xxx(1)</tt> will return a pointer to an A object, which
1231 will be wrapped in a CLOS instance of class <tt>A</tt>, and a
1232 call to <tt>yyy(1)</tt> will result in a CLOS instance of
1233 type <tt>Foo</tt> being returned. Without establishing a clear
1234 type relationship between <tt>Foo</tt> and <tt>A</tt>, an
1235 attempt to call <tt>zzz(yyy(1))</tt> will result in an error.
1239 We resolve this issue, by noting synonym relationships between
1240 types while generating the interface. A Primary type is selected
1241 (more on this below) from the candidate list of synonyms. For
1242 all other synonyms, intead of generating a distinct CLOS class
1243 definition, we generate a form that expands to:
1245 <div class="targetlang">
1246 <tt>(setf (find-class <synonym>) <primary>)</tt>
1249 The result is that all references to synonym types in foreign
1250 code, are wrapped in the same CLOS wrapper, and, in particular,
1251 method specialization in wrapping generic functions works as
1256 Given the above header file, synonym.h, a Lisp session would
1259 <div class="targetlang">
1261 CL-USER> (load "synonym.dll")
1262 ; Foreign loading synonym.dll.
1264 CL-USER> (load "synonym.cl")
1265 ; Loading c:\mikel\src\swig\test\synonym.cl
1268 synonym> (setf a (xxx 3))
1269 #<A nil #x3261a0 @ #x207299da>
1270 synonym> (setf foo (yyy 10))
1271 #<A nil #x3291d0 @ #x2072e982>
1274 synonym> (zzz foo)
1280 <H4><a name="Allegrocl_nn29"></a>17.3.8.1 Choosing a primary type</H4>
1284 The choice of a primary type is selected by the following
1285 criteria from a set of synonym types.
1289 If a synonym type has a class definition, it is the primary type.
1292 If a synonym type is a class template and has been explicitly
1293 instantiated via <tt>%template</tt>, it is the primary type.
1296 For all other sets of synonymous types, the synonym which is
1297 parsed first becomes the primary type.
1301 <H3><a name="Allegrocl_nn30"></a>17.3.9 Function overloading/Parameter defaulting</H3>
1305 For each possible argument combination, a distinct wrapper
1306 function is created in the .cxx file. On the Lisp side, a
1307 generic functions is defined for each possible arity the
1308 overloaded/defaulted call may have. Each distinct wrapper is
1309 then called from within a defmethod on the appropriate generic
1310 function. These are further wrapped inside a dispatch function
1311 that checks the number of arguments it is called with and passes
1312 them via apply to the appropriate generic-function. This allows
1313 for a single entry point to overloaded functions on the lisp
1319 <div class="code">overload.h:
1328 float xxx(int i, int x = 0); /* return i * x */
1329 float xxx(A *inst, int x); /* return x + A->x + A->y */
1333 <p>Creates the following three wrappers, for each of the possible argument
1336 <div class="code">overload_wrap.cxx
1338 EXPORT void ACL___delete_A__SWIG_0 (A *larg1) {
1351 EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) {
1352 float lresult = (float)0 ;
1360 result = (float)xxx(arg1,arg2);
1370 EXPORT float ACL___xxx__SWIG_1 (int larg1) {
1371 float lresult = (float)0 ;
1377 result = (float)xxx(arg1);
1387 EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) {
1388 float lresult = (float)0 ;
1396 result = (float)xxx(arg1,arg2);
1408 And the following foreign-function-call and method definitions on the
1411 <div class="targetlang">overload.cl
1413 (swig-defmethod ("xxx" "ACL___xxx__SWIG_0" :type :function :arity 2)
1414 ((PARM0_i cl:integer :int )
1415 (PARM1_x cl:integer :int ))
1416 (:returning (:float )
1418 (let ((SWIG_arg0 PARM0_i))
1419 (let ((SWIG_arg1 PARM1_x))
1420 (swig-ff-call SWIG_arg0 SWIG_arg1))))
1422 (swig-defmethod ("xxx" "ACL___xxx__SWIG_1" :type :function :arity 1)
1423 ((PARM0_i cl:integer :int ))
1424 (:returning (:float )
1426 (let ((SWIG_arg0 PARM0_i))
1427 (swig-ff-call SWIG_arg0)))
1429 (swig-defmethod ("xxx" "ACL___xxx__SWIG_2" :type :function :arity 2)
1430 ((PARM0_inst #.(swig-insert-id "A" () :type :class) (* #.(swig-insert-id "A" ())) )
1431 (PARM1_x cl:integer :int ))
1432 (:returning (:float )
1434 (let ((SWIG_arg0 PARM0_inst))
1435 (let ((SWIG_arg1 PARM1_x))
1436 (swig-ff-call SWIG_arg0 SWIG_arg1))))
1438 (swig-dispatcher ("xxx" :type :function :arities (1 2)))
1442 <p>And their usage in a sample lisp session:
1444 <div class="targetlang">
1446 overload> (setf a (new_A))
1447 #<A nil #x329268 @ #x206cf612>
1448 overload> (setf (A_x a) 10)
1450 overload> (setf (A_y a) 20)
1452 overload> (xxx 1)
1454 overload> (xxx 3 10)
1456 overload> (xxx a 1)
1458 overload> (xxx a 2)
1464 <H3><a name="Allegrocl_nn31"></a>17.3.10 Operator wrapping and Operator overloading</H3>
1468 Wrappers to defined C++ Operators are automatically renamed, using
1469 <tt>%rename</tt>, to the following defaults:
1473 /* name conversion for overloaded operators. */
1475 %rename(__add__) *::operator+;
1476 %rename(__pos__) *::operator+();
1477 %rename(__pos__) *::operator+() const;
1479 %rename(__sub__) *::operator-;
1480 %rename(__neg__) *::operator-() const;
1481 %rename(__neg__) *::operator-();
1483 %rename(__mul__) *::operator*;
1484 %rename(__deref__) *::operator*();
1485 %rename(__deref__) *::operator*() const;
1487 %rename(__div__) *::operator/;
1488 %rename(__mod__) *::operator%;
1489 %rename(__logxor__) *::operator^;
1490 %rename(__logand__) *::operator&;
1491 %rename(__logior__) *::operator|;
1492 %rename(__lognot__) *::operator~();
1493 %rename(__lognot__) *::operator~() const;
1495 %rename(__not__) *::operator!();
1496 %rename(__not__) *::operator!() const;
1498 %rename(__assign__) *::operator=;
1500 %rename(__add_assign__) *::operator+=;
1501 %rename(__sub_assign__) *::operator-=;
1502 %rename(__mul_assign__) *::operator*=;
1503 %rename(__div_assign__) *::operator/=;
1504 %rename(__mod_assign__) *::operator%=;
1505 %rename(__logxor_assign__) *::operator^=;
1506 %rename(__logand_assign__) *::operator&=;
1507 %rename(__logior_assign__) *::operator|=;
1509 %rename(__lshift__) *::operator<<;
1510 %rename(__lshift_assign__) *::operator<<=;
1511 %rename(__rshift__) *::operator>>;
1512 %rename(__rshift_assign__) *::operator>>=;
1514 %rename(__eq__) *::operator==;
1515 %rename(__ne__) *::operator!=;
1516 %rename(__lt__) *::operator<;
1517 %rename(__gt__) *::operator>;
1518 %rename(__lte__) *::operator<=;
1519 %rename(__gte__) *::operator>=;
1521 %rename(__and__) *::operator&&;
1522 %rename(__or__) *::operator||;
1524 %rename(__preincr__) *::operator++();
1525 %rename(__postincr__) *::operator++(int);
1526 %rename(__predecr__) *::operator--();
1527 %rename(__postdecr__) *::operator--(int);
1529 %rename(__comma__) *::operator,();
1530 %rename(__comma__) *::operator,() const;
1532 %rename(__member_ref__) *::operator->;
1533 %rename(__member_func_ref__) *::operator->*;
1535 %rename(__funcall__) *::operator();
1536 %rename(__aref__) *::operator[];
1541 Name mangling occurs on all such renamed identifiers, so that wrapper name
1542 generated by <tt>B::operator=</tt> will be <tt>B___eq__</tt>, i.e.
1543 <tt><class-or-namespace>_</tt> has been added. Users may modify
1544 these default names by adding <tt>%rename</tt> directives in their own .i files.
1548 Operator overloading can be achieved by adding functions based
1549 on the mangled names of the function. In the following example,
1550 a class B is defined with a Operator== method defined. The
1551 swig <tt>%extend</tt> directive is used to add an overload method
1555 <div class="code">opoverload.h
1561 bool operator==(B const& other) const;
1569 <div class="code">opoverload.i
1574 #include <fstream>
1575 #include "opoverload.h"
1579 bool B___eq__(B const *inst, int const x)
1581 // insert the function definition into the wrapper code before
1582 // the wrapper for it.
1587 %include "opoverload.h"
1591 bool __eq__(int const x) const;
1597 Either operator can be called via a single call
1598 to the dispatch function:
1600 <div class="targetlang">
1602 opoverload> (B___eq__ x1 x2)
1604 opoverload> (B___eq__ x1 3)
1610 <H3><a name="Allegrocl_nn32"></a>17.3.11 Varargs</H3>
1614 Variable length argument lists are not supported, by default. If
1615 such a function is encountered, a warning will generated to
1616 stderr. Varargs are supported via the SWIG <tt>%vararg</tt>
1617 directive. This directive allows you to specify a (finite)
1618 argument list which will be inserted into the wrapper in place
1619 of the variable length argument indicator. As an example,
1620 consider the function <tt>printf()</tt>. It's declaration would
1625 See the following section
1626 on <a href="Varargs.html#Varargs">Variable Length arguments</a>
1627 provides examples on how <tt>%vararg</tt> can be used, along
1628 with other ways such functions can be wrapped.
1631 <H3><a name="Allegrocl_nn33"></a>17.3.12 C++ Exceptions</H3>
1635 Each C++ wrapper includes a handler to catch any exceptions that may
1636 be thrown while in foreign code. This helps prevent simple C++ errors
1637 from killing the entire lisp process. There is currently no mechanism
1638 to have these exceptions forwarded to the lisp condition system, nor
1639 has any explicit support of the exception related SWIG typemaps been
1643 <H3><a name="Allegrocl_nn34"></a>17.3.13 Pass by value, pass by reference</H3>
1647 Allegro CL does not support the passing of non-primitive foreign
1648 structures by value. As a result, SWIG must automatically detect
1649 and convert function parameters and return values to pointers
1650 whenever necessary. This is done via the use of <tt>typemaps</tt>,
1651 and should not require any fine tuning by the user, even for
1652 newly defined types.
1655 <H2><a name="Allegrocl_nn35"></a>17.4 Typemaps</H2>
1659 SWIG Typemaps provide a powerful tool for automatically generating
1660 code to handle various menial tasks required of writing an interface
1661 to foreign code. The purpose of this section is to describe each of
1662 the typemaps used by the Allegro CL module. Please read the chapter
1663 on <a href="Typemaps.html#Typemaps">Typemaps</a> for more information.
1666 <H3><a name="Allegrocl_nn36"></a>17.4.1 Code Generation in the C++ Wrapper</H3>
1671 Every C++ wrapper generated by SWIG takes the following form:
1674 <div class="diagram">
1676 return-val wrapper-name(parm0, parm1, ..., parmN)
1678 return-val lresult; /* return value from wrapper */
1679 <local-declaration>
1680 ... results; /* return value from function call */
1682 <binding locals to parameters>
1685 result = function-name(local0, local1, ..., localN);
1687 <convert and bind result to lresult>
1696 <H4><a name="Allegrocl_nn37"></a>17.4.1.1 IN Typemap</H4>
1700 the <tt>in</tt> typemap is used to generate code to convert parameters
1701 passed to C++ wrapper functions into the arguments desired for the
1702 call being wrapped. That is, it fills in the code for the
1703 <tt><binding locals to parameters></tt> section above. We
1704 use this map to automatically convert parameters passed by
1705 reference to the wrapper function into by-value arguments for
1706 the wrapped call, and also to convert boolean values, which are
1707 passed as integers from lisp (by default), into the appropriate
1708 type for the language of code being wrapped.
1711 <p>These are the default specifications for the IN typemap. Here,
1712 <tt>$input</tt> refers to the parameter code is being generated
1713 for, and <tt>$1</tt> is the local variable to which it is
1714 being assigned. The default settings of this typemap are as follows:
1719 %typemap(in) bool "$1 = (bool)$input;";
1720 %typemap(in) char, unsigned char, signed char,
1721 short, signed short, unsigned short,
1722 int, signed int, unsigned int,
1723 long, signed long, unsigned long,
1724 float, double, long double, char *, void *, void,
1725 enum SWIGTYPE, SWIGTYPE *,
1726 SWIGTYPE[ANY], SWIGTYPE & "$1 = $input;";
1727 %typemap(in) SWIGTYPE "$1 = *$input;";
1731 <H4><a name="Allegrocl_nn38"></a>17.4.1.2 OUT Typemap</H4>
1735 The <tt>out</tt> typemap is used to generate code to form the
1736 return value of the wrapper from the return value of the wrapped
1737 function. This code is placed in the <convert and bind result to lresult>
1738 section of the above code diagram. It's default mapping is as follows:
1743 %typemap(out) bool "$result = (int)$1;";
1744 %typemap(out) char, unsigned char, signed char,
1745 short, signed short, unsigned short,
1746 int, signed int, unsigned int,
1747 long, signed long, unsigned long,
1748 float, double, long double, char *, void *, void,
1749 enum SWIGTYPE, SWIGTYPE *,
1750 SWIGTYPE[ANY], SWIGTYPE & "$result = $1;";
1751 %typemap(out) SWIGTYPE "$result = new $1_type($1);";
1755 <H4><a name="Allegrocl_nn39"></a>17.4.1.3 CTYPE Typemap</H4>
1759 This typemap is not used for code generation, but purely for the
1760 transformation of types in the parameter list of the wrapper function.
1761 It's primary use is to handle by-value to by-reference conversion in the
1762 wrappers parameter list. Its default settings are:
1767 %typemap(ctype) bool "int";
1768 %typemap(ctype) char, unsigned char, signed char,
1769 short, signed short, unsigned short,
1770 int, signed int, unsigned int,
1771 long, signed long, unsigned long,
1772 float, double, long double, char *, void *, void,
1773 enum SWIGTYPE, SWIGTYPE *,
1774 SWIGTYPE[ANY], SWIGTYPE & "$1_ltype";
1775 %typemap(ctype) SWIGTYPE "$&1_type";
1780 These three typemaps are specifically employed by the the
1781 Allegro CL interface generator. SWIG also implements a number of
1782 other typemaps that can be used for generating code in the C/C++
1783 wrappers. You can read about
1784 these <a href="Typemaps.html#Typemaps_nn25">common typemaps</a> here.
1787 <H3><a name="Allegrocl_nn40"></a>17.4.2 Code generation in Lisp wrappers</H3>
1791 A number of custom typemaps have also been added to facilitate
1792 the generation of code in the lisp side of the interface. These
1793 are described below. The basic code generation structure is
1794 applied as a series of nested expressions, one for each
1795 parameter, then one for manipulating the return value, and last,
1796 the foreign function call itself.
1800 Note that the typemaps below use fully qualified symbols where
1801 necessary. Users writing their own typemaps should do likewise.
1802 See the explanation in the last paragraph of
1803 <a href="#Allegrocl_nn15">16.3.1 Namespaces</a> for details.
1806 <H4><a name="Allegrocl_nn41"></a>17.4.2.1 LIN Typemap</H4>
1810 The LIN typemap allows for the manipulating the lisp objects
1811 passed as arguments to the wrapping defun before passing them to
1812 the foreign function call. For example, when passing lisp
1813 strings to foreign code, it is often necessary to copy the
1814 string into a foreign structure of type (:char *) of appropriate
1815 size, and pass this copy to the foreign call. Using the LIN
1816 typemap, one could arrange for the stack-allocation of a foreign
1817 char array, copy your string into it, and not have to worry
1818 about freeing the copy after the function returns.
1821 <p>The LIN typemap accepts the following <tt>$variable</tt> references.
1824 <li><tt>$in</tt> - expands to the name of the parameter being
1825 applied to this typemap
1827 <li><tt>$out</tt> - expands to the name of the local variable
1828 assigned to this typemap
1830 <li><tt>$in_fftype</tt> - the foreign function type of the C type.</li>
1831 <li><tt>$*in_fftype</tt> - the foreign function type of the C type
1832 with one pointer removed. If there is no pointer, then $*in_fftype
1833 is the same as $in_fftype.
1835 <li><tt>$body</tt> - very important. Instructs SWIG where
1836 subsequent code generation steps should be inserted into the
1837 current typemap. Leaving out a <tt>$body</tt> reference
1838 will result in lisp wrappers that do very little by way of
1839 calling into foreign code. Not recommended.
1845 %typemap(lin) SWIGTYPE "(cl:let (($out $in))\n $body)";
1849 <H4><a name="Allegrocl_nn42"></a>17.4.2.2 LOUT Typemap</H4>
1853 The LOUT typemap is the means by which we effect the wrapping of
1854 foreign pointers in CLOS instances. It is applied after all LIN
1855 typemaps, and immediately before the actual foreign-call.
1858 <p>The LOUT typemap uses the following $variable
1861 <li><tt>$lclass</tt> - Expands to the CLOS class that
1862 represents foreign-objects of the return type matching this
1865 <li><tt>$body</tt> - Same as for the LIN map. Place this
1866 variable where you want the foreign-function call to occur.
1868 <li><tt>$ldestructor</tt> - Expands to the symbol naming the destructor for this
1869 class ($lclass) of object. Allows you to insert finalization or automatic garbage
1870 collection into the wrapper code (see default mappings below).
1876 %typemap(lout) bool, char, unsigned char, signed char,
1877 short, signed short, unsigned short,
1878 int, signed int, unsigned int,
1879 long, signed long, unsigned long,
1880 float, double, long double, char *, void *, void,
1881 enum SWIGTYPE "$body";
1882 %typemap(lout) SWIGTYPE[ANY], SWIGTYPE *,
1883 SWIGTYPE & "(cl:make-instance '$lclass :foreign-address $body)";
1884 %typemap(lout) SWIGTYPE "(cl:let* ((address $body)\n
1885 (ACL_result (cl:make-instance '$lclass :foreign-address address)))\n
1886 (cl:unless (cl::zerop address)\n
1887 (excl:schedule-finalization ACL_result #'$ldestructor))\n
1892 <H4><a name="Allegrocl_nn43"></a>17.4.2.3 FFITYPE Typemap</H4>
1897 The FFITYPE typemap works as a helper for a body of code that
1898 converts C/C++ type specifications into Allegro CL foreign-type
1899 specifications. These foreign-type specifications appear in
1900 ff:def-foreing-type declarations, and in the argument list and
1901 return values of ff:def-foreign-calls. You would modify this
1902 typemap if you want to change how the FFI passes through
1903 arguments of a given type. For example, if you know that a
1904 particular compiler represents booleans as a single byte, you
1905 might add an entry for:
1910 %typemap(ffitype) bool ":unsigned-char";
1915 Note that this typemap is pure type transformation, and is not
1916 used in any code generations step the way the LIN and LOUT
1917 typemaps are. The default mappings for this typemap are:
1922 %typemap(ffitype) bool ":int";
1923 %typemap(ffitype) char ":char";
1924 %typemap(ffitype) unsigned char ":unsigned-char";
1925 %typemap(ffitype) signed char ":char";
1926 %typemap(ffitype) short, signed short ":short";
1927 %typemap(ffitype) unsigned short ":unsigned-short";
1928 %typemap(ffitype) int, signed int ":int";
1929 %typemap(ffitype) unsigned int ":unsigned-int";
1930 %typemap(ffitype) long, signed long ":long";
1931 %typemap(ffitype) unsigned long ":unsigned-long";
1932 %typemap(ffitype) float ":float";
1933 %typemap(ffitype) double ":double";
1934 %typemap(ffitype) char * "(* :char)";
1935 %typemap(ffitype) void * "(* :void)";
1936 %typemap(ffitype) void ":void";
1937 %typemap(ffitype) enum SWIGTYPE ":int";
1938 %typemap(ffitype) SWIGTYPE & "(* :void)";
1942 <H4><a name="Allegrocl_nn44"></a>17.4.2.4 LISPTYPE Typemap</H4>
1946 This is another type only transformation map, and is used to
1947 provide the lisp-type, which is the optional third argument in
1948 argument specifier in a ff:def-foreign-call form. Specifying a
1949 lisp-type allows the foreign call to perform type checking on
1950 the arguments passed in. The default entries in this typemap are:
1955 %typemap(lisptype) bool "cl:boolean";
1956 %typemap(lisptype) char "cl:character";
1957 %typemap(lisptype) unsigned char "cl:integer";
1958 %typemap(lisptype) signed char "cl:integer";
1962 <H4><a name="Allegrocl_nn45"></a>17.4.2.5 LISPCLASS Typemap</H4>
1966 The LISPCLASS typemap is used to generate the method signatures
1967 for the generic-functions which wrap overloaded functions and
1968 functions with defaulted arguments. The default entries are:
1973 %typemap(lispclass) bool "t";
1974 %typemap(lispclass) char "cl:character";
1975 %typemap(lispclass) unsigned char, signed char,
1976 short, signed short, unsigned short,
1977 int, signed int, unsigned int,
1978 long, signed long, unsigned long,
1979 enum SWIGTYPE "cl:integer";
1980 %typemap(lispclass) float "cl:single-float";
1981 %typemap(lispclass) double "cl:double-float";
1982 %typemap(lispclass) char * "cl:string";
1986 <H3><a name="Allegrocl_nn46"></a>17.4.3 Modifying SWIG behavior using typemaps</H3>
1990 The following example shows how we made use of the above
1991 typemaps to add support for the wchar_t type.
1996 %typecheck(SWIG_TYPECHECK_UNICHAR) wchar_t { $1 = 1; };
1998 %typemap(in) wchar_t "$1 = $input;";
1999 %typemap(lin) wchar_t "(cl:let (($out (cl:char-code $in)))\n $body)";
2000 %typemap(lin) wchar_t* "(excl:with-native-string
2002 :external-format #+little-endian :fat-le
2003 #-little-endian :fat)\n
2006 %typemap(out) wchar_t "$result = $1;";
2007 %typemap(lout) wchar_t "(cl:code-char $body)";
2008 %typemap(lout) wchar_t* "(excl:native-to-string $body
2009 :external-format #+little-endian :fat-le
2010 #-little-endian :fat)";
2012 %typemap(ffitype) wchar_t ":unsigned-short";
2013 %typemap(lisptype) wchar_t "";
2014 %typemap(ctype) wchar_t "wchar_t";
2015 %typemap(lispclass) wchar_t "cl:character";
2016 %typemap(lispclass) wchar_t* "cl:string";
2020 <H2><a name="Allegrocl_nn47"></a>17.5 Identifier Converter functions</H2>
2023 <H3><a name="Allegrocl_nn48"></a>17.5.1 Creating symbols in the lisp environment</H3>
2027 Various symbols must be generated in the lisp environment to which
2028 class definitions, functions, constants, variables, etc. must be
2029 bound. Rather than force a particular convention for naming these
2030 symbols, an identifier (to symbol) conversion function is used. A
2031 user-defined identifier-converter can then implement any symbol
2032 naming, case-modifying, scheme desired.
2036 In generated SWIG code, whenever some interface object must be
2037 referenced by its lisp symbol, a macro is inserted that calls the
2038 identifier-converter function to generate the appropriate symbol
2039 reference. It is therefore expected that the identifier-converter
2040 function reliably return the same (eq) symbol given the same set
2044 <H3><a name="Allegrocl_nn49"></a>17.5.2 Existing identifier-converter functions</H3>
2047 <p>Two basic identifier routines have been defined.
2048 <H4><a name="Allegrocl_nn50"></a>17.5.2.1 identifier-convert-null</H4>
2052 No modification of the identifier string is performed. Based on
2053 other arguments, the identifier may be concatenated with other
2054 strings, from which a symbol will be created.
2057 <H4><a name="Allegrocl_nn51"></a>17.5.2.2 identifier-convert-lispify</H4>
2061 All underscores in the identifier string are converted to
2062 hyphens. Otherwise, identifier-convert-lispify performs the
2063 same symbol transformations.
2066 <H4><a name="Allegrocl_nn52"></a>17.5.2.3 Default identifier to symbol conversions</H4>
2070 Check the definitions of the above two default
2071 identifier-converters in <tt>Lib/allegrocl/allegrocl.swg</tt> for
2072 default naming conventions.
2075 <H3><a name="Allegrocl_nn53"></a>17.5.3 Defining your own identifier-converter</H3>
2079 A user-defined identifier-converter function should conform to the following
2083 <div class="targetlang">
2085 (defun identifier-convert-fn (id &key type class arity) ...body...)
2086 result ==> symbol or (setf symbol)
2090 <p>The <tt>ID</tt> argument is a string representing an identifier in the
2091 foreign environment.
2095 The :type keyword argument provides more information on the type of
2096 identifier. It's value is a symbol. This allows the
2097 identifier-converter to apply different heuristics when mapping
2098 different types of identifiers to symbols. SWIG will generate calls
2099 to your identifier-converter using the following types.
2103 <li>:class - names a CLOS class.</li>
2104 <li>:constant - names a defconstant</li>
2105 <li>:constructor - names a function for creating a foreign object</li>
2106 <li>:destructor - names a function for freeing a foreign object</li>
2107 <li>:function - names a CLOS wrapping defmethod or defun.</li>
2108 <li>:ff-operator - names a foreign call defined via ff:def-foreign-call</li>
2109 <li>:getter - getter function</li>
2110 <li>:namespace - names a C++ namespace</li>
2111 <li>:setter - names a setter function. May return a (setf symbol) reference</li>
2112 <li>:operator - names a C++ operator, such as Operator=, Operator*.</li>
2113 <li>:slot - names a slot in a struct/class/union declaration.</li>
2114 <li>:type - names a foreign-type defined via ff:def-foreign-type.</li>
2115 <li>:variable - names a variable defined via ff:def-foreign-variable.</li>
2119 The :class keyword argument is a string naming a foreign
2120 class. When non-nil, it indicates that the current identifier has
2121 scope in the specified class.
2125 The :arity keyword argument only appears in swig:swig-defmethod forms
2126 generated for overloaded functions. It's value is an integer
2127 indicating the number of arguments passed to the routine indicated by
2131 <H3><a name="Allegrocl_nn54"></a>17.5.4 Instructing SWIG to use a particular identifier-converter</H3>
2135 By default, SWIG will use identifier-converter-null. To specify
2136 another convert function, use the <tt>-identifier-converter</tt>
2137 command-line argument. The value should be a string naming the
2138 function you wish the interface to use instead, when generating
2144 % swig -allegrocl -c++ -module mymodule -identifier-converter my-identifier-converter