Diff of /ffi.xmlf [9e7c20] .. [c13f92] Maximize Restore

  Switch to unified view

a/ffi.xmlf b/ffi.xmlf
...
...
17
  <para>A FFI is made of at least three components:</para>
17
  <para>A FFI is made of at least three components:</para>
18
  <variablelist>
18
  <variablelist>
19
   <varlistentry>
19
   <varlistentry>
20
    <term>Foreign objects management</term>
20
    <term>Foreign objects management</term>
21
    <listitem><para>This is the data that the foreign code will use. A &FFI;
21
    <listitem><para>This is the data that the foreign code will use. A &FFI;
22
    needs to provide means to buid and manipulate foreign data, with atomatic
22
    needs to provide means to buid and manipulate foreign data, with automatic
23
    conversions to and from lisp data types whenever possible, and it also has
23
    conversions to and from lisp data types whenever possible, and it also has
24
    to deal with issues like garbage collection and
24
    to deal with issues like garbage collection and
25
    finalization.</para></listitem>
25
    finalization.</para></listitem>
26
   </varlistentry>
26
   </varlistentry>
27
   <varlistentry>
27
   <varlistentry>
...
...
220
  of using the native &UFFI; and the &CFFI; library.</para>
220
  of using the native &UFFI; and the &CFFI; library.</para>
221
221
222
  <section id="ext.ffi.uffi-example">
222
  <section id="ext.ffi.uffi-example">
223
   <title>UFFI example</title>
223
   <title>UFFI example</title>
224
224
225
   <para>The example below shows how to use &UFFI; in an application. There are
226
   several important ingredients:
227
   <itemizedlist>
228
    <listitem><para>You need to specify the libraries you use and do it at the
229
    toplevel, so that the compiler may include them at link
230
    time.</para></listitem>
231
    <listitem><para>Every function you will use has to be declared using
232
    <function>uffi:def-function</function>.</para></listitem>
233
   </itemizedlist>
234
   </para>
225
<programlisting>
235
<programlisting>
226
 
236
#|
237
Build and load this module with (compile-file "uffi.lsp" :load t)
238
|#
239
;;
240
;; This toplevel statement notifies the compiler that we will
241
;; need this shared library at runtime. We do not need this
242
;; statement in windows.
243
;;
244
#-(or ming32 windows)
245
(uffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
246
             #-darwin "/usr/lib/libm.so")
247
;;
248
;; With this other statement, we import the C function sin(),
249
;; which operates on IEEE doubles.
250
;;
251
(uffi:def-function ("sin" c-sin) ((arg :double))
252
                   :returning :double)
253
;;
254
;; We now use this function and compare with the lisp version.
255
;;
256
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
257
  (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
227
</programlisting>
258
</programlisting>
228
  </section>
259
  </section>
229
260
230
  <section id="ext.ffi.cffi-example">
261
  <section id="ext.ffi.cffi-example">
231
   <title>CFFI example</title>
262
   <title>CFFI example</title>
232
263
264
   <para>The &CFFI; library is an independent project and it is not shipped
265
   with &ECL;. If you wish to use it you can go to their <ulink
266
   url="http://www.common-lisp.net/cffi/">homepage</ulink>, download the code
267
   and build it using &ASDF;.</para>
268
269
   <para>&CFFI; differs slightly from &UFFI; in that functions may be used even
270
   without being declared beforehand. This poses a few problems to the &ECL;
271
   backend, but hopefully these should have been solved in the latest
272
   releases.</para>
233
<programlisting>
273
<programlisting>
234
 
274
#|
275
Build and load this module with (compile-file "cffi.lsp" :load t)
276
|#
277
;;
278
;; This toplevel statement notifies the compiler that we will
279
;; need this shared library at runtime. We do not need this
280
;; statement in windows.
281
;;
282
#-(or ming32 windows)
283
(cffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
284
             #-darwin "/usr/lib/libm.so")
285
;;
286
;; With this other statement, we import the C function sin(),
287
;; which operates on IEEE doubles.
288
;;
289
(cffi:defcfun ("sin" c-sin) :double :double)
290
;;
291
;; We now use this function and compare with the lisp version.
292
;;
293
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
294
  (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
295
;;
296
;; The following also works: no declaration!
297
;;
298
(let ((c-cos (cffi:foreign-funcall "cos" :double 1.0d0 :double)))
299
   (format t "~%Lisp cos:~t~d~%C cos:~t~d~%Difference:~t~d"
300
  (sin 1.0d0) c-sin (- (sin 1.0d0) c-sin)))
301
</programlisting>
302
  </section>
303
304
  <section id="ext.ffi.ecl-example">
305
   <title>Low level example</title>
306
307
   <para>To compare with the previous pieces of code, we show how the previous
308
   programs would be written using <xref linkend="ref.clines"/> and <xref
309
   linkend="ref.c-inline"/></para>
310
<programlisting>
311
#|
312
Build and load this module with (compile-file "ecl.lsp" :load t)
313
|#
314
;;
315
;; With this other statement, we import the C function sin(), which
316
;; operates on IEEE doubles. Notice that we include the C header to
317
;; get the full declaration.
318
;;
319
(defun c-sin (x)
320
  (ffi:clines "#include &lt;math.h&gt;")
321
  (ffi:c-inline (x) (:double) :double "sin(#0)" :one-liner t))
322
;;
323
;; We now use this function and compare with the lisp version.
324
;;
325
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
326
  (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
235
</programlisting>
327
</programlisting>
236
  </section>
328
  </section>
237
 </section>
329
 </section>
238
330
239
 <section id="ext.ffi.dict">
331
 <section id="ext.ffi.dict">
...
...
269
361
270
   <refsect1>
362
   <refsect1>
271
    <title>Description</title>
363
    <title>Description</title>
272
364
273
    <para>This special form inserts C code directly in the file that results
365
    <para>This special form inserts C code directly in the file that results
274
    from compiling lisp sources. It can only appear as a toplevel form and,
366
    from compiling lisp sources. Contrary to <xref linkend="ref.c-inline"/>,
275
    contrary to <xref linkend="ref.c-inline"/>, it does not accept any input
367
    this function may have no executable statements, accepts no input value and
276
    values nor returns any value.</para>
368
    returnsn no value.</para>
277
369
278
    <para>The main use of <function>FFI:CLINES</function> is to declare or
370
    <para>The main use of <function>FFI:CLINES</function> is to declare or
279
    define C variables and functions that are going to be used later in other
371
    define C variables and functions that are going to be used later in other
280
    &FFI; statements.</para>
372
    &FFI; statements.</para>
281
373
...
...
314
      <funcdef>ffi:c-inline</funcdef>
406
      <funcdef>ffi:c-inline</funcdef>
315
      <paramdef>(<parameter>lisp-value</parameter>*)</paramdef>
407
      <paramdef>(<parameter>lisp-value</parameter>*)</paramdef>
316
      <paramdef>(<parameter>c-type</parameter>*)</paramdef>
408
      <paramdef>(<parameter>c-type</parameter>*)</paramdef>
317
      <paramdef><parameter>return-type</parameter></paramdef>
409
      <paramdef><parameter>return-type</parameter></paramdef>
318
      <paramdef><parameter>C-code</parameter></paramdef>
410
      <paramdef><parameter>C-code</parameter></paramdef>
319
      <paramdef>&keys;</paramdef>
411
      <paramdef>&key;</paramdef>
320
      <paramdef><parameter>one-liner</parameter></paramdef>
412
      <paramdef><parameter>one-liner</parameter></paramdef>
321
      <paramdef><parameter>side-effects</parameter></paramdef>
413
      <paramdef><parameter>side-effects</parameter></paramdef>
322
     </funcprototype>
414
     </funcprototype>
323
    </funcsynopsis>
415
    </funcsynopsis>
324
    <simplelist columns="2" type="horiz">
416
    <simplelist columns="2" type="horiz">