File: foreign-function-calls.html

package info (click to toggle)
sbcl 1%3A0.8.16-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 15,028 kB
  • ctags: 14,790
  • sloc: lisp: 194,656; ansic: 16,544; asm: 2,060; sh: 1,674; makefile: 199
file content (155 lines) | stat: -rw-r--r-- 11,635 bytes parent folder | download
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
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /><title>Foreign Function Calls</title><meta name="generator" content="DocBook XSL Stylesheets V1.62.4" /><link rel="home" href="index.html" title="SBCL User Manual" /><link rel="up" href="ffi.html" title="Chapter5.The Foreign Function Interface" /><link rel="previous" href="load-object.html" title="Loading Unix Object Files" /><link rel="next" href="ffi-example.html" title="Step-By-Step Example of the Foreign Function Interface" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Foreign Function Calls</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="load-object.html">Prev</a></td><th width="60%" align="center">Chapter5.The Foreign Function Interface</th><td width="20%" align="right"><a accesskey="n" href="ffi-example.html">Next</a></td></tr></table><hr /></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="foreign-function-calls"></a>Foreign Function Calls</h2></div></div><div></div></div><p>
The foreign function call interface allows a Lisp program to call
many functions written in languages that use the C calling convention.
</p><p>
Lisp sets up various signal handling routines and other environment
information when it first starts up, and expects these to be in place
at all times. The C functions called by Lisp should not change the
environment, especially the signal handlers: the signal handlers
installed by Lisp typically have interesting flags set (e.g to request
machine context information, or for signal delivery on an alternate
stack) which the Lisp runtime relies on for correct operation.
Precise details of how this works may change without notice between
versions; the source, or the brain of a friendly <span class="application">SBCL</span> developer,
is the only documentation.  Users of a Lisp built with the :sb-thread
feature should also read the Threading section 
 
of this manual</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2928010"></a>The <tt class="function">alien-funcall</tt> Primitive</h3></div></div><div></div></div><pre class="synopsis">(sb-alien:alien-funcall alien-function &amp;rest arguments)</pre><p>
The <tt class="function">alien-funcall</tt> function is the foreign function call
primitive: <tt class="varname">alien-function</tt> is called with the supplied
<tt class="varname">arguments</tt> and its C return value is returned as a Lisp value.
The <tt class="varname">alien-function</tt> is an arbitrary
run-time expression; to refer to a constant function, use
<tt class="function">extern-alien</tt> or a value defined by
<tt class="function">define-alien-routine</tt>.
</p><p>
The type of <tt class="function">alien-function</tt>
must be <tt class="type">(alien (function ...))</tt>
or <tt class="type">(alien (* (function ...)))</tt>.
The function type is used to
determine how to call the function (as though it was declared with
a prototype.)  The type need not be known at compile time, but only
known-type calls are efficiently compiled.  Limitations:
</p><div class="itemizedlist"><ul type="disc"><li><p>Structure type return values are not implemented.</p></li><li><p>Passing of structures by value is not implemented.</p></li></ul></div><p>
</p><p>
Here is an example which allocates a <tt class="type">(struct foo)</tt>, calls a foreign
function to initialize it, then returns a Lisp vector of all the
<tt class="type">(* (struct foo))</tt> objects filled in by the foreign call:
</p><pre class="programlisting">
;; Allocate a foo on the stack.
(with-alien ((f (struct foo)))
  ;; Call some C function to fill in foo fields.
  (alien-funcall (extern-alien &quot;mangle_foo&quot; (function void (* foo)))
                 (addr f))
  ;; Find how many foos to use by getting the A field.
  (let* ((num (slot f 'a))
         (result (make-array num)))
    ;; Get a pointer to the array so that we don't have to keep extracting it:
    (with-alien ((a (* (array (* (struct foo)) 100)) (addr (slot f 'b))))
      ;; Loop over the first N elements and stash them in the result vector.
      (dotimes (i num)
        (setf (svref result i) (deref (deref a) i)))
      ;; Voila.
      result)))</pre><p>
</p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2901125"></a>The <tt class="function">define-alien-routine</tt> Macro</h3></div></div><div></div></div><pre class="synopsis">(sb-alien:define-alien-routine} name result-type &amp;rest arg-specifiers)</pre><p>
The <tt class="function">define-alien-routine</tt> macro is a convenience
for automatically generating Lisp
interfaces to simple foreign functions.  The primary feature is the
parameter style specification, which translates the C
pass-by-reference idiom into additional return values.
</p><p>
<tt class="varname">name</tt> is usually a string external symbol, but may also be a
symbol Lisp name or a list of the foreign name and the Lisp name.
If only one name is specified, the other is automatically derived
as for <tt class="function">extern-alien</tt>.
<tt class="varname">result-type</tt> is the alien type of the return value.
</p><p>
Each element of the <tt class="varname">arg-specifiers</tt> list 
specifies an argument to the foreign function, and is
of the form
</p><pre class="programlisting">(aname atype &amp;optional style)</pre><p>
<tt class="varname">aname</tt> is the symbol name of the argument to the constructed
function (for documentation). <tt class="varname">atype</tt> is the alien type of
corresponding foreign argument.  The semantics of the actual call
are the same as for <tt class="function">alien-funcall</tt>. <tt class="varname">style</tt>
specifies how this argument should be handled at call and return time,
and should be one of the following
</p><div class="itemizedlist"><ul type="disc"><li><p><tt class="varname">:in</tt>specifies that the argument is
    passed by value. This is the default. <tt class="varname">:in</tt> arguments
    have no corresponding return value from the Lisp function.
    </p></li><li><p><tt class="varname">:copy</tt> is similar to <tt class="varname">:in</tt>,
    but the argument is copied
    to a pre-allocated object and a pointer to this object is passed
    to the foreign routine.</p></li><li><p><tt class="varname">:out</tt> specifies a pass-by-reference
    output value.  The type of the argument must be a pointer to
    a fixed-sized object (such as an integer or pointer).
    <tt class="varname">:out</tt> and <tt class="varname">:in-out</tt> style cannot
    be used with pointers to arrays, records or functions.  An
    object of the correct size is allocated on the stack, and
    its address is passed to the foreign function.  When the
    function returns, the contents
    of this location are returned as one of the values of the Lisp
    function (and the location is automatically deallocated).
    </p></li><li><p><tt class="varname">:in-out</tt> is a combination of
    <tt class="varname">:copy</tt> and <tt class="varname">:out</tt>.
    The argument is copied to a pre-allocated object and a pointer to
    this object is passed to the foreign routine.  On return, the
    contents of this location is returned as an additional value.
    </p></li></ul></div><p>
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
Any efficiency-critical foreign interface function should be inline
expanded, which can be done by preceding the
<tt class="function">define-alien-routine</tt> call with:
</p><pre class="programlisting">(declaim (inline lisp-name))</pre><p>
In addition to avoiding the Lisp call overhead, this allows
pointers, word-integers and floats to be passed using non-descriptor
representations, avoiding consing.)
</p></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2956187"></a><tt class="function">define-alien-routine</tt> Example</h3></div></div><div></div></div><p>
Consider the C function <tt class="function">cfoo</tt>
with the following calling convention:
</p><pre class="programlisting">
void
cfoo (str, a, i)
    char *str;
    char *a; /* update */
    int *i; /* out */
{
  /* body of cfoo(...) */
}</pre><p>
This can be described by the following call to
<tt class="function">define-alien-routine</tt>:
</p><pre class="programlisting">
(define-alien-routine &quot;cfoo&quot; void
  (str c-string)
  (a char :in-out)
  (i int :out))</pre><p>
The Lisp function <tt class="function">cfoo</tt> will have
two arguments (<tt class="varname">str</tt> and <tt class="varname">a</tt>)
and two return values (<tt class="varname">a</tt> and <tt class="varname">i</tt>).
</p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2956237"></a>Calling Lisp From C</h3></div></div><div></div></div><p>
Calling Lisp functions from C is sometimes possible, but is extremely
hackish and poorly supported as of <span class="application">SBCL</span> 0.7.5.
See <tt class="function">funcall0</tt> ... <tt class="function">funcall3</tt> in
the runtime system. The
arguments must be valid <span class="application">SBCL</span> object descriptors (so that 
e.g. fixnums must be
left-shifted by 2.) As of <span class="application">SBCL</span> 0.7.5, the format
of object descriptors is documented only by the source code and, in parts, 
by the old <span class="application">CMU CL</span> &quot;INTERNALS&quot; documentation.</p><p> Note that the garbage collector moves objects, and won't be
able to fix up any references in C variables.  There are three
mechanisms for coping with this: 
</p><div class="orderedlist"><ol type="1"><li><p>The <tt class="function">sb-ext:purify</tt> moves all live Lisp
data into static or read-only areas such that it will never be moved
(or freed) again in the life of the Lisp session</p></li><li><p><tt class="function">sb-sys:with-pinned-objects</tt> is a
macro which arranges for some set of objects to be pinned in memory
for the dynamic extent of its body forms.  On ports which use the
generational garbage collector (as of <span class="application">SBCL</span> 0.8.3, only the x86) this
has a page granularity - i.e. the entire 4k page or pages containing
the objects will be locked down. On other ports it is implemented by
turning off GC for the duration (so could be said to have a
whole-world granularity).  </p></li><li><p>Disable GC, using the <tt class="function">without-gcing</tt>
macro or <tt class="function">gc-off</tt> call.</p></li></ol></div><p>

</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="load-object.html">Prev</a></td><td width="20%" align="center"><a accesskey="u" href="ffi.html">Up</a></td><td width="40%" align="right"><a accesskey="n" href="ffi-example.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Loading Unix Object Files</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">Step-By-Step Example of the Foreign Function Interface</td></tr></table></div></body></html>