Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>SWIG and Common Lisp</title> | |
5 | <link rel="stylesheet" type="text/css" href="style.css"> | |
6 | </head> | |
7 | ||
8 | <body bgcolor="#ffffff"> | |
9 | <H1><a name="Lisp_nn1"></a>30 SWIG and Common Lisp</H1> | |
10 | <!-- INDEX --> | |
11 | <div class="sectiontoc"> | |
12 | <ul> | |
13 | <li><a href="Lisp.html#Lisp_nn2">Allegro Common Lisp</a> | |
14 | <li><a href="Lisp.html#Lisp_nn3">CLISP</a> | |
15 | <li><a href="Lisp.html#Lisp_nn4">UFFI</a> | |
16 | </ul> | |
17 | </div> | |
18 | <!-- INDEX --> | |
19 | ||
20 | <p> | |
21 | Common Lisp is a high-level, all-purpose, object-oriented, | |
22 | dynamic, functional programming language with long history. | |
23 | Common Lisp is used in many fields, ranging from web development to | |
24 | finance, and also common in computer science education. | |
25 | There are more than 9 different implementations of common lisp which | |
26 | are available, all have different foreign function | |
27 | interfaces. SWIG currently supports only the Allegro Common | |
28 | Lisp, CLisp and UFFI foreign function interfaces. | |
29 | </p> | |
30 | <H2><a name="Lisp_nn2"></a>30.1 Allegro Common Lisp</H2> | |
31 | <p> | |
32 | </p> | |
33 | <H2><a name="Lisp_nn3"></a>30.2 CLISP</H2> | |
34 | <p> | |
35 | <a href="http://clisp.cons.org">CLISP</a> is a feature-loaded | |
36 | implementation of common lisp which is portable across most of the | |
37 | operating system environments and hardware. CLISP includes an | |
38 | interpreter, a compiler, a debugger, CLOS, MOP, a foreign | |
39 | language interface, i18n, regular expressions, a socket | |
40 | interface, and more. An X11 interface is available through CLX, | |
41 | Garnet and CLUE/CLIO. Command line editing is provided by | |
42 | readline. CLISP runs Maxima, ACL2 and many other Common Lisp | |
43 | packages. <br/> | |
44 | ||
45 | To run the SWIG module of clisp requires very little effort, you | |
46 | just need to execute: | |
47 | ||
48 | <div class="code"><pre> | |
49 | swig -clispcl -module <i>module-name</i> <i>file-name</i> | |
50 | ||
51 | </pre></div> | |
52 | ||
53 | Because of the high level nature of the CLISP FFI, the bindings | |
54 | generated by SWIG may not be absolutely correct, and you may need | |
55 | to modify them. The good thing is that you don't need to complex | |
56 | interface file for the CLISP module. The CLISP module tries to | |
57 | produce code which is both human readable and easily modifyable. | |
58 | </p> | |
59 | <H3><a name="Lisp_nn4"></a>30.2.1 Additional Commandline Options </H3> | |
60 | ||
61 | <p> | |
62 | The following table list the additional commandline options available for the CLISP module. They can also be seen by using: | |
63 | </p> | |
64 | ||
65 | <div class="code"><pre> | |
66 | swig -clisp -help | |
67 | </pre></div> | |
68 | <br/> | |
69 | <table summary="CLISP specific options"> | |
70 | <tr> | |
71 | <th>CLISP specific options</th> | |
72 | </tr> | |
73 | ||
74 | <tr> | |
75 | <td>-extern-all</td> | |
76 | <td>If this option is given then clisp definitions for all the functions<br/> | |
77 | and global variables will be created otherwise only definitions for<br/> | |
78 | externed functions and variables are created. | |
79 | </td> | |
80 | </tr> | |
81 | ||
82 | <tr> | |
83 | <td>-generate-typedef</td> | |
84 | <td>If this option is given then def-c-type will be used to generate<br/> | |
85 | shortcuts according to the typedefs in the input. | |
86 | </td> | |
87 | </tr> | |
88 | ||
89 | </table> | |
90 | ||
91 | <H3><a name="Lisp_nn5"></a>30.2.2 Details on CLISP bindings</H3> | |
92 | ||
93 | <p> | |
94 | As mentioned earlier the CLISP bindings generated by SWIG may need | |
95 | some modifications. The clisp module creates a lisp file with | |
96 | the same name as the module name. This | |
97 | lisp file contains a 'defpackage' declaration, with the | |
98 | package name same as the module name. This package uses the | |
99 | 'common-lisp' and 'ffi' packages. Also, package exports all | |
100 | the functions, structures and variables for which an ffi | |
101 | binding was generated.<br/> | |
102 | After generating the defpackage statement, the clisp module also | |
103 | sets the default language. | |
104 | ||
105 | <div class="targetlang"><pre> | |
106 | (defpackage :test | |
107 | (:use :common-lisp :ffi) | |
108 | (:export | |
109 | :make-bar | |
110 | :bar-x | |
111 | :bar-y | |
112 | :bar-a | |
113 | :bar-b | |
114 | :bar-z | |
115 | :bar-n | |
116 | :pointer_func | |
117 | :func123 | |
118 | :make-cfunr | |
119 | :lispsort_double | |
120 | :test123)) | |
121 | ||
122 | (in-package :test) | |
123 | ||
124 | (default-foreign-language :stdc) | |
125 | </pre></div> | |
126 | <p> | |
127 | The ffi wrappers for functions and variables are generated as shown | |
128 | below. When functions have arguments of type "double * array", | |
129 | SWIG doesn't knows whether it is an 'out' argument or it is | |
130 | an array which will be passed, so SWIG plays it safe by | |
131 | declaring it as an '(array (ffi:c-ptr DOUBLE-FLOAT))'. For | |
132 | arguments of type "int **z[100]" where SWIG has more | |
133 | information, i.e., it knows that 'z' is an array of pointers to | |
134 | pointers of integers, SWIG defines it to be '(z (ffi:c-ptr | |
135 | (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))' | |
136 | </p> | |
137 | <div class="code"><pre> | |
138 | extern "C" { | |
139 | int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int y); | |
140 | ||
141 | int func123(div_t * x,int **z[100],int y[][1000][10]); | |
142 | ||
143 | void lispsort_double (int n, double * array); | |
144 | ||
145 | void test123(float x , double y); | |
146 | ||
147 | } | |
148 | </pre></div> | |
149 | <div class="targetlang"><pre> | |
150 | (ffi:def-call-out pointer_func | |
151 | (:name "pointer_func") | |
152 | (:arguments (ClosureFun (ffi:c-function (:arguments (arg0 (ffi:c-pointer NIL)) | |
153 | (arg1 (ffi:c-pointer NIL)) | |
154 | (arg2 (ffi:c-pointer NIL))) | |
155 | (:return-type NIL))) | |
156 | (y ffi:int)) | |
157 | (:return-type ffi:int) | |
158 | (:library +library-name+)) | |
159 | ||
160 | (ffi:def-call-out func123 | |
161 | (:name "func123") | |
162 | (:arguments (x (ffi:c-pointer div_t)) | |
163 | (z (ffi:c-ptr (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100))) | |
164 | (y (ffi:c-ptr (ffi:c-ptr (ffi:c-array ffi:int (1000 10)))))) | |
165 | (:return-type ffi:int) | |
166 | (:library +library-name+)) | |
167 | ||
168 | ||
169 | (ffi:def-call-out lispsort_double | |
170 | (:name "lispsort_double") | |
171 | (:arguments (n ffi:int) | |
172 | (array (ffi:c-ptr DOUBLE-FLOAT))) | |
173 | (:return-type NIL) | |
174 | (:library +library-name+)) | |
175 | ||
176 | (ffi:def-call-out test123 | |
177 | (:name "test") | |
178 | (:arguments (x SINGLE-FLOAT) | |
179 | (y DOUBLE-FLOAT)) | |
180 | (:return-type NIL) | |
181 | (:library +library-name+)) | |
182 | ||
183 | </pre></div> | |
184 | ||
185 | <p> | |
186 | The module also handles strutcures and #define constants as shown | |
187 | below. SWIG automatically adds the constructors and accessors | |
188 | created for the struct to the list of symbols exported by the | |
189 | package. | |
190 | </p> | |
191 | <div class="code"><pre> | |
192 | struct bar { | |
193 | short x, y; | |
194 | char a, b; | |
195 | int *z[1000]; | |
196 | struct bar * n; | |
197 | }; | |
198 | ||
199 | #define max 1000 | |
200 | </pre></div> | |
201 | <div class="targetlang"><pre> | |
202 | (ffi:def-c-struct bar | |
203 | (x :type ffi:short) | |
204 | (y :type ffi:short) | |
205 | (a :type character) | |
206 | (b :type character) | |
207 | (z :type (ffi:c-array (ffi:c-ptr ffi:int) 1000)) | |
208 | (n :type (ffi:c-pointer bar))) | |
209 | ||
210 | (defconstant max 1000) | |
211 | ||
212 | </pre></div> | |
213 | ||
214 | <H2><a name="Lisp_nn6"></a>30.3 UFFI </H2> | |
215 | <p> | |
216 | ||
217 | </p> | |
218 | </body> | |
219 | </html> |