Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > e3d62627d1d1aab7ab1be2dd7f65a872 > files > 268

ecl-10.4.1-1.fc14.x86_64.rpm

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>3.4.&#160;Higher level interfaces</title><link rel="stylesheet" href="ecl.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><link rel="home" href="index.html" title="The ECL manual"><link rel="up" href="ch18.html" title="Chapter&#160;3.&#160;Foreign Function Interface"><link rel="prev" href="ch18s03.html" title="3.3.&#160;Foreign objects"><link rel="next" href="ch18s05.html" title="3.5.&#160;FFI Reference"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3.4.&#160;Higher level interfaces</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch18s03.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;3.&#160;Foreign Function Interface</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch18s05.html">Next</a></td></tr></table><hr></div><div class="section" title="3.4.&#160;Higher level interfaces"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ext.ffi.uffi.and.cffi"></a>3.4.&#160;Higher level interfaces</h2></div></div></div><p>Up to now we have only discussed vague ideas about how a <span class="application">FFI</span> works,
  but you are probably more interested on how to actually code all these things
  in lisp. You have here three possibilities:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p><span class="application">ECL</span> supplies a high level interface which is compatible with
    <a class="link" href="pt04.html" title="Part&#160;IV.&#160;UFFI Reference"><span class="application">UFFI</span></a>. Code designed for this library should run mostly unchanged with
    <span class="application">ECL</span>.</p></li><li class="listitem"><p>The <span class="application">CFFI</span> library features a mostly complete backend for <span class="application">ECL</span>. This
    is however a work in progress, as the fact that <span class="application">CFFI</span> allows for calling
    arbitrary functions without declaring them causes some troubles with
    <span class="application">ECL</span>.</p></li><li class="listitem"><p><span class="application">ECL</span>'s own low level interface. Only to be used if <span class="application">ECL</span> is your
    deployment platform. It features some powerful constructs that allow you to
    merge arbitrary C code with lisp (<a class="xref" href="re14.html" title="ffi:c-inline"><code class="function">ffi:c-inline</code></a> and <a class="xref" href="re13.html" title="ffi:clines"><code class="function">ffi:clines</code></a>).</p></li></ul></div><p>In the following two subsections we will discuss two practical examples
  of using the native <a class="link" href="pt04.html" title="Part&#160;IV.&#160;UFFI Reference"><span class="application">UFFI</span></a> and the <span class="application">CFFI</span> library.</p><div class="section" title="3.4.1.&#160;UFFI example"><div class="titlepage"><div><div><h3 class="title"><a name="ext.ffi.uffi-example"></a>3.4.1.&#160;UFFI example</h3></div></div></div><p>The example below shows how to use <a class="link" href="pt04.html" title="Part&#160;IV.&#160;UFFI Reference"><span class="application">UFFI</span></a> in an application. There are
   several important ingredients:
   </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>You need to specify the libraries you use and do it at the
    toplevel, so that the compiler may include them at link
    time.</p></li><li class="listitem"><p>Every function you will use has to be declared using
    <code class="function">uffi:def-function</code>.</p></li></ul></div><p>
   </p><pre class="programlisting">
#|
Build and load this module with (compile-file "uffi.lsp" :load t)
|#
;;
;; This toplevel statement notifies the compiler that we will
;; need this shared library at runtime. We do not need this
;; statement in windows.
;;
#-(or ming32 windows)
(uffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
			   #-darwin "/usr/lib/libm.so")
;;
;; With this other statement, we import the C function sin(),
;; which operates on IEEE doubles.
;;
(uffi:def-function ("sin" c-sin) ((arg :double))
                   :returning :double)
;;
;; We now use this function and compare with the lisp version.
;;
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
	(sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
</pre></div><div class="section" title="3.4.2.&#160;CFFI example"><div class="titlepage"><div><div><h3 class="title"><a name="ext.ffi.cffi-example"></a>3.4.2.&#160;CFFI example</h3></div></div></div><p>The <span class="application">CFFI</span> library is an independent project and it is not shipped
   with <span class="application">ECL</span>. If you wish to use it you can go to their <a class="ulink" href="http://www.common-lisp.net/cffi/" target="_top">homepage</a>, download the code
   and build it using <span class="application">ASDF</span>.</p><p><span class="application">CFFI</span> differs slightly from <a class="link" href="pt04.html" title="Part&#160;IV.&#160;UFFI Reference"><span class="application">UFFI</span></a> in that functions may be used even
   without being declared beforehand. This poses a few problems to the <span class="application">ECL</span>
   backend, but hopefully these should have been solved in the latest
   releases.</p><pre class="programlisting">
#|
Build and load this module with (compile-file "cffi.lsp" :load t)
|#
;;
;; This toplevel statement notifies the compiler that we will
;; need this shared library at runtime. We do not need this
;; statement in windows.
;;
#-(or ming32 windows)
(cffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
			   #-darwin "/usr/lib/libm.so")
;;
;; With this other statement, we import the C function sin(),
;; which operates on IEEE doubles.
;;
(cffi:defcfun ("sin" c-sin) :double '(:double))
;;
;; We now use this function and compare with the lisp version.
;;
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
	(sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
;;
;; The following also works: no declaration!
;;
(let ((c-cos (cffi:foreign-funcall "cos" :double 1.0d0 :double)))
   (format t "~%Lisp cos:~t~d~%C cos:~t~d~%Difference:~t~d"
	(sin 1.0d0) c-sin (- (sin 1.0d0) c-sin)))
</pre></div><div class="section" title="3.4.3.&#160;Low level example"><div class="titlepage"><div><div><h3 class="title"><a name="ext.ffi.ecl-example"></a>3.4.3.&#160;Low level example</h3></div></div></div><p>To compare with the previous pieces of code, we show how the previous
   programs would be written using <a class="xref" href="re13.html" title="ffi:clines"><code class="function">ffi:clines</code></a> and <a class="xref" href="re14.html" title="ffi:c-inline"><code class="function">ffi:c-inline</code></a></p><pre class="programlisting">
#|
Build and load this module with (compile-file "ecl.lsp" :load t)
|#
;;
;; With this other statement, we import the C function sin(), which
;; operates on IEEE doubles. Notice that we include the C header to
;; get the full declaration.
;;
(defun c-sin (x)
  (ffi:clines "#include &lt;math.h&gt;")
  (ffi:c-inline (x) (:double) :double "sin(#0)" :one-liner t))
;;
;; We now use this function and compare with the lisp version.
;;
(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
	(sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch18s03.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="ch18.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="ch18s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.3.&#160;Foreign objects&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;3.5.&#160;FFI Reference</td></tr></table></div></body></html>