mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-13 04:42:13 -08:00
514 lines
14 KiB
XML
514 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!DOCTYPE book [
|
|
<!ENTITY % eclent SYSTEM "../ecl.ent">
|
|
%eclent;
|
|
]>
|
|
<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
|
|
<reference xml:id="uffi.strings">
|
|
<title>Strings</title>
|
|
<partintro>
|
|
<title>Overview</title>
|
|
<para>
|
|
&UFFI; has functions to two types of <varname>C</varname>-compatible
|
|
strings: <emphasis>cstring</emphasis> and <emphasis>foreign</emphasis>
|
|
strings. cstrings are used <emphasis>only</emphasis> as parameters to
|
|
and from functions. In some implementations a cstring is not a foreign
|
|
type but rather the Lisp string itself. On other platforms a cstring
|
|
is a newly allocated foreign vector for storing characters. The
|
|
following is an example of using cstrings to both send and return a
|
|
value.
|
|
</para>
|
|
|
|
<programlisting>
|
|
(uffi:def-function ("getenv" c-getenv)
|
|
((name :cstring))
|
|
:returning :cstring)
|
|
|
|
(defun my-getenv (key)
|
|
"Returns an environment variable, or NIL if it does not exist"
|
|
(check-type key string)
|
|
(uffi:with-cstring (key-native key)
|
|
(uffi:convert-from-cstring (c-getenv key-native))))
|
|
</programlisting>
|
|
|
|
<para>In contrast, foreign strings are always a foreign vector of characters
|
|
which have memory allocated. Thus, if you need to allocate memory to hold
|
|
the return value of a string, you must use a foreign string and not a
|
|
cstring. The following is an example of using a foreign string for a return
|
|
value.</para>
|
|
|
|
<programlisting>
|
|
(uffi:def-function ("gethostname" c-gethostname)
|
|
((name (* :unsigned-char))
|
|
(len :int))
|
|
:returning :int)
|
|
|
|
(defun gethostname ()
|
|
"Returns the hostname"
|
|
(let* ((name (uffi:allocate-foreign-string 256))
|
|
(result-code (c-gethostname name 256))
|
|
(hostname (when (zerop result-code)
|
|
(uffi:convert-from-foreign-string name))))
|
|
;; UFFI does not yet provide a universal way to free
|
|
;; memory allocated by C's malloc. At this point, a program
|
|
;; needs to call C's free function to free such memory.
|
|
(unless (zerop result-code)
|
|
(error "gethostname() failed."))))</programlisting>
|
|
|
|
<para>Foreign functions that return pointers to freshly allocated strings
|
|
should in general not return cstrings, but foreign strings. (There is no
|
|
portable way to release such cstrings from Lisp.) The following is an
|
|
example of handling such a function.</para>
|
|
|
|
<programlisting>
|
|
(uffi:def-function ("readline" c-readline)
|
|
((prompt :cstring))
|
|
:returning (* :char))
|
|
|
|
(defun readline (prompt)
|
|
"Reads a string from console with line-editing."
|
|
(with-cstring (c-prompt prompt)
|
|
(let* ((c-str (c-readline c-prompt))
|
|
(str (convert-from-foreign-string c-str)))
|
|
(uffi:free-foreign-object c-str)
|
|
str)))
|
|
</programlisting>
|
|
|
|
</partintro>
|
|
|
|
<refentry xml:id="uffi.convert-from-cstring">
|
|
<refnamediv>
|
|
<refname><function>convert-from-cstring</function></refname>
|
|
<refpurpose>Converts a cstring to a Lisp string.</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>convert-from-cstring</function>
|
|
<replaceable>cstring</replaceable>
|
|
=>
|
|
<returnvalue>string</returnvalue>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>cstring</parameter></term>
|
|
<listitem>
|
|
<para>A cstring.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><returnvalue>string</returnvalue></term>
|
|
<listitem>
|
|
<para>A Lisp string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Converts a Lisp string to a <constant>cstring</constant>. This is
|
|
most often used when processing the results of a foreign function
|
|
that returns a cstring.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
|
|
<refentry xml:id="uffi.convert-to-cstring">
|
|
<refnamediv>
|
|
<refname><function>convert-to-cstring</function></refname>
|
|
<refpurpose>Converts a Lisp string to a cstring.</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>convert-to-cstring</function>
|
|
<replaceable>string</replaceable>
|
|
=>
|
|
<returnvalue>cstring</returnvalue>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>string</parameter></term>
|
|
<listitem>
|
|
<para>A Lisp string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><returnvalue>cstring</returnvalue></term>
|
|
<listitem>
|
|
<para>A cstring.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Converts a Lisp string to a <varname>cstring</varname>. The
|
|
<varname>cstring</varname> should be freed with
|
|
<function>free-cstring</function>.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>On some implementations, this function allocates memory.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
|
|
<refentry xml:id="uffi.free-cstring">
|
|
<refnamediv>
|
|
<refname><function>free-cstring</function></refname>
|
|
<refpurpose>Free memory used by cstring.
|
|
</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>free-cstring</function> <replaceable>cstring</replaceable>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>cstring</parameter></term>
|
|
<listitem>
|
|
<para>A cstring.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Frees any memory possibly allocated by
|
|
<function>convert-to-cstring</function>. On some implementions, a cstring is just the Lisp string itself.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
|
|
<refentry xml:id="uffi.with-cstring">
|
|
<refnamediv>
|
|
<refname><function>with-cstring</function></refname>
|
|
<refpurpose>Binds a newly created cstring.</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>with-cstring</function>
|
|
<replaceable>(cstring string) {body}</replaceable>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>cstring</parameter></term>
|
|
<listitem>
|
|
<para>A symbol naming the cstring to be created.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>string</parameter></term>
|
|
<listitem>
|
|
<para>A Lisp string that will be translated to a cstring.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>body</parameter></term>
|
|
<listitem>
|
|
<para>The body of where the cstring will be bound.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Binds a symbol to a cstring created from conversion of a
|
|
string. Automatically frees the <varname>cstring</varname>.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Examples</title>
|
|
<para>
|
|
<programlisting>
|
|
(def-function ("getenv" c-getenv)
|
|
((name :cstring))
|
|
:returning :cstring)
|
|
|
|
(defun getenv (key)
|
|
"Returns an environment variable, or NIL if it does not exist"
|
|
(check-type key string)
|
|
(with-cstring (key-cstring key)
|
|
(convert-from-cstring (c-getenv key-cstring))))</programlisting>
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
|
|
<refentry xml:id="uffi.convert-from-foreign-string">
|
|
<refnamediv>
|
|
<refname><function>convert-from-foreign-string</function></refname>
|
|
<refpurpose>Converts a foreign string into a Lisp string.</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>convert-from-foreign-string</function>
|
|
<replaceable>foreign-string &key length null-terminated-p</replaceable>
|
|
=>
|
|
<returnvalue>string</returnvalue>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>foreign-string</parameter></term>
|
|
<listitem>
|
|
<para>A foreign string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>length</parameter></term>
|
|
<listitem>
|
|
<para>The length of the foreign string to convert. The
|
|
default is the length of the string until a &NULL;
|
|
character is reached.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>null-terminated-p</parameter></term>
|
|
<listitem>
|
|
<para>A boolean flag with a default value of &t; When true,
|
|
the string is converted until the first &NULL; character is reached.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><returnvalue>string</returnvalue></term>
|
|
<listitem>
|
|
<para>A Lisp string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Returns a Lisp string from a foreign string.
|
|
Can translated ASCII and binary strings.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
|
|
<refentry xml:id="uffi.convert-to-foreign-string">
|
|
<refnamediv>
|
|
<refname><function>convert-to-foreign-string</function></refname>
|
|
<refpurpose>Converts a Lisp string to a foreign string.
|
|
</refpurpose>
|
|
<refclass>Macro</refclass>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Syntax</title>
|
|
<synopsis>
|
|
<function>convert-to-foreign-string</function>
|
|
<replaceable>string</replaceable> =>
|
|
<returnvalue>foreign-string</returnvalue>
|
|
</synopsis>
|
|
</refsynopsisdiv>
|
|
<refsect1>
|
|
<title>Arguments and Values</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>string</parameter></term>
|
|
<listitem>
|
|
<para>A Lisp string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><returnvalue>foreign-string</returnvalue></term>
|
|
<listitem>
|
|
<para>A foreign string.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Converts a Lisp string to a foreign string. Memory should be
|
|
freed with <function>free-foreign-object</function>.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
<refentry xml:id="uffi.allocate-foreign-string">
|
|
<refnamediv>
|
|
<refname><function>allocate-foreign-string</function></refname>
|
|
<refpurpose>Allocates space for a foreign string.
|
|
</refpurpose>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<title>Macro</title>
|
|
<synopsis>
|
|
<function>allocate-foreign-string</function> <replaceable>size
|
|
&key unsigned</replaceable> =>
|
|
<returnvalue>foreign-string</returnvalue>
|
|
</synopsis>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><parameter>size</parameter></term>
|
|
<listitem>
|
|
<para>The size of the space to be allocated in bytes.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><parameter>unsigned</parameter></term>
|
|
<listitem>
|
|
<para>A boolean flag with a default value of &t;. When true,
|
|
marks the pointer as an <constant>:unsigned-char</constant>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><returnvalue>foreign-string</returnvalue></term>
|
|
<listitem>
|
|
<para>A foreign string which has undefined contents.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsynopsisdiv>
|
|
|
|
<refsect1>
|
|
<title>Description</title>
|
|
<para>
|
|
Allocates space for a foreign string. Memory should
|
|
be freed with <function>free-foreign-object</function>.
|
|
</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Side Effects</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Affected by</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
<refsect1>
|
|
<title>Exceptional Situations</title>
|
|
<para>None.</para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
</reference>
|
|
</book>
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: nxml
|
|
sgml-indent-step: 1
|
|
nxml-child-indent: 1
|
|
nxml-outline-child-indent: 0
|
|
fill-column: 79
|
|
End:
|
|
-->
|