File: foreign-values.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 (86 lines) | stat: -rw-r--r-- 9,609 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
<?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>Operations On Foreign Values</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="foreign-types.html" title="Foreign Types" /><link rel="next" href="foreign-variables.html" title="Foreign Variables" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Operations On Foreign Values</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="foreign-types.html">Prev</a></td><th width="60%" align="center">Chapter5.The Foreign Function Interface</th><td width="20%" align="right"><a accesskey="n" href="foreign-variables.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-values"></a>Operations On Foreign Values</h2></div></div><div></div></div><p>This section describes how to read foreign values as Lisp
values, how to coerce foreign values to different kinds of foreign values, and
how to dynamically allocate and free foreign variables.</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2966578"></a>Accessing Foreign Values</h3></div></div><div></div></div><pre class="synopsis">(sb-alien:deref pointer-or-array &amp;rest indices)</pre><p>The <tt class="function">sb-alien:deref</tt> function returns the value pointed to by
a foreign pointer, or the value of a foreign array element. When
dereferencing a pointer, an optional single index can be specified to
give the equivalent of C pointer arithmetic; this index is scaled by
the size of the type pointed to. When dereferencing an array, the
number of indices must be the same as the number of dimensions in the
array type. <tt class="function">deref</tt> can be set with <tt class="function">setf</tt> to
assign a new value.</p><pre class="synopsis">(sb-alien:slot struct-or-union &amp;rest slot-names)</pre><p>The <tt class="function">sb-alien:slot</tt> function extracts the value of
the slot named <tt class="varname">slot-name</tt> from a foreign <tt class="type">struct</tt> or
<tt class="type">union</tt>. If <tt class="varname">struct-or-union</tt> is a pointer to a
structure or union, then it is automatically dereferenced.
<tt class="function">sb-alien:slot</tt> can be set with <tt class="function">setf</tt> to assign
a new value. Note that <tt class="varname">slot-name</tt> is evaluated, and need
not be a compile-time constant (but only constant slot accesses are
efficiently compiled.)</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2966654"></a>Untyped memory</h4></div></div><div></div></div><p>As noted at the beginning of the chapter, the System Area
Pointer facilities allow untyped access to foreign memory.  SAPs can
be converted to and from the usual typed foreign values using
<tt class="function">sap-alien</tt> and <tt class="function">alien-sap</tt>
(described elsewhere), and also to and from integers - raw machine
addresses.  They should thus be used with caution; corrupting the Lisp
heap or other memory with SAPs is trivial.</p><pre class="synopsis">(sb-sys:int-sap machine-address)</pre><p>Creates a SAP pointing at the virtual address
<tt class="varname">machine-address</tt>.  </p><pre class="synopsis">(sb-sys:sap-ref-32 sap offset)</pre><p>Access the value of the memory location at
<tt class="varname">offset</tt> bytes from <tt class="varname">sap</tt>.  This form
may also be used with <tt class="function">setf</tt> to alter the memory at
that location.</p><pre class="synopsis">(sb-sys:sap= sap1 sap2)</pre><p>Compare <tt class="varname">sap1</tt> and <tt class="varname">sap2</tt> for
equality.</p><p>Similarly named functions exist for accessing other sizes of
word, other comparisons, and other conversions.  The reader is invited
to use <tt class="function">apropos</tt> and <tt class="function">describe</tt>
for more details</p><pre class="programlisting">
(apropos &quot;sap&quot; :sb-sys)
</pre></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2966744"></a>Coercing Foreign Values</h3></div></div><div></div></div><pre class="synopsis">(sb-alien:addr alien-expr)</pre><p>
The <tt class="function">sb-alien:addr</tt> macro
returns a pointer to the location specified by
<tt class="varname">alien-expr</tt>, which must be either a foreign variable, a use of
<tt class="function">sb-alien:deref</tt>, a use of <tt class="function">sb-alien:slot</tt>, or a use of
<tt class="function">sb-alien:extern-alien</tt>.
</p><pre class="synopsis">(sb-alien:cast foreign-value new-type)</pre><p>The <tt class="function">sb-alien:cast</tt>
converts <tt class="varname">foreign-value</tt> to a new foreign value with the specified
<tt class="varname">new-type</tt>. Both types, old and new, must be foreign pointer,
array or function types.  Note that the resulting Lisp 
foreign variable object 
is not <tt class="function">eq</tt> to the
argument, but it does refer to the same foreign data bits.</p><pre class="synopsis">(sb-alien:sap-alien sap type)</pre><p>The <tt class="function">sb-alien:sap-alien</tt> function converts <tt class="varname">sap</tt>
(a system area pointer) to a foreign value with the specified
<tt class="varname">type</tt>. <tt class="varname">type</tt> is not evaluated.
</p><p>The <tt class="varname">type</tt> must be some foreign pointer, array, or
record type.</p><pre class="synopsis">(sb-alien:alien-sap foreign-value type)</pre><p>The <tt class="function">sb-alien:alien-sap</tt> function
returns the SAP which points to <tt class="varname">alien-value</tt>'s data.
</p><p>The <tt class="varname">foreign-value</tt> must be of some foreign pointer,
array, or record type.</p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2920625"></a>Foreign Dynamic Allocation</h3></div></div><div></div></div><p>Lisp code can call the C standard library functions
<tt class="function">malloc</tt> and <tt class="function">free</tt> to dynamically allocate and
deallocate foreign variables. The Lisp code shares the same allocator
with foreign C code, so it's OK for foreign code to call
<tt class="function">free</tt> on the result of Lisp
<tt class="function">sb-alien:make-alien</tt>, or for Lisp code to call
<tt class="function">sb-alien:free-alien</tt> on foreign objects allocated by C
code.</p><pre class="synopsis">(sb-alien:make-alien type size)</pre><p>The <tt class="function">sb-alien:make-alien</tt> macro
returns a dynamically allocated foreign value of the specified
<tt class="varname">type</tt> (which is not evaluated.)  The allocated memory is not
initialized, and may contain arbitrary junk.  If supplied,
<tt class="varname">size</tt> is an expression to evaluate to compute the size of the
allocated object.  There are two major cases:
</p><div class="itemizedlist"><ul type="disc"><li><p>When <tt class="varname">type</tt> is a foreign array type, an array of
    that type is allocated and a pointer to it is returned.  Note that you
    must use <tt class="function">deref</tt> to change the result to an array before you
    can use <tt class="function">deref</tt> to read or write elements:
    </p><pre class="programlisting">
      (cl:in-package &quot;CL-USER&quot;) ; which USEs package &quot;SB-ALIEN&quot;
      (defvar *foo* (make-alien (array char 10)))
      (type-of *foo*) =&gt; (alien (* (array (signed 8) 10)))
      (setf (deref (deref foo) 0) 10) =&gt; 10</pre><p>
    If supplied, <tt class="varname">size</tt> is used as the first dimension for the
    array.</p></li><li><p>When <tt class="varname">type</tt> is any other foreign type, then an
    object for that type is allocated, and a pointer to it is
    returned.  So <tt class="function">(make-alien int)</tt> returns a <tt class="type">(* int)</tt>.
    If <tt class="varname">size</tt> is specified, then a block of that many
    objects is allocated, with the result pointing to the first one.</p></li></ul></div><p>
</p><pre class="synopsis">(sb-alien:free-alien foreign-value)</pre><p>The <tt class="function">sb-alien:free-alien</tt> function
frees the storage for <tt class="varname">foreign-value</tt>, 
which must have been allocated with Lisp <tt class="function">make-alien</tt>
or C <tt class="function">malloc</tt>.</p><p>See also the <tt class="function">sb-alien:with-alien</tt> macro, which
allocates foreign values on the stack.</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="foreign-types.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="foreign-variables.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Foreign Types</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">Foreign Variables</td></tr></table></div></body></html>