</para>
<itemizedlist>
<listitem>
- <para><constant>:char</constant> - Signed 8-bits</para>
+ <para><constant>:char</constant> - Signed 8-bits. A
+dereferenced :char pointer returns an character.</para>
</listitem>
<listitem>
- <para><constant>:unsigned-char</constant> - Unsigned 8-bits</para>
+ <para><constant>:unsigned-char</constant> - Unsigned 8-bits. A dereferenced :unsigned-char
+pointer returns an character.</para>
</listitem>
<listitem>
- <para><constant>:short</constant> - Signed 16-bits</para>
+ <para><constant>:byte</constant> - Signed 8-bits. A
+dereferenced :byte pointer returns an integer.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-byte</constant> - Unsigned 8-bits. A
+dereferenced :unsigned-byte pointer returns an integer.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:short</constant> - Signed 16-bits.</para>
</listitem>
<listitem>
- <para><constant>:unsigned-short</constant> - Unsigned 16-bits</para>
+ <para><constant>:unsigned-short</constant> - Unsigned 16-bits.</para>
</listitem>
<listitem>
- <para><constant>:int</constant> - Signed 32-bits</para>
+ <para><constant>:int</constant> - Signed 32-bits.</para>
</listitem>
<listitem>
- <para><constant>:unsigned-int</constant> - Unsigned 32-bits</para>
+ <para><constant>:unsigned-int</constant> - Unsigned 32-bits.</para>
</listitem>
<listitem>
- <para><constant>:long</constant> - Signed 32-bits</para>
+ <para><constant>:long</constant> - Signed 32 or 64 bits, depending upon the platform.</para>
</listitem>
<listitem>
- <para><constant>:unsigned-long</constant> - Unsigned 32-bits</para>
+ <para><constant>:unsigned-long</constant> - Unsigned 32 or 64 bits, depending upon the platform.</para>
</listitem>
<listitem>
- <para><constant>:float</constant> - 32-bit floating point</para>
+ <para><constant>:float</constant> - 32-bit floating point.</para>
</listitem>
<listitem>
- <para><constant>:double</constant> - 64-bit floating point</para>
+ <para><constant>:double</constant> - 64-bit floating point.</para>
</listitem>
<listitem>
<para><constant>:cstring</constant> -
-A null-terminated string used for passing and returning with a function.
+A &null; terminated string used for passing and returning characters strings with a &c; function.
</para>
</listitem>
<listitem>
<para><constant>:void</constant> -
-The absence of a value. Used in generic pointers and in return types from functions.</para>
+The absence of a value. Used to indicate that a function does not return a value.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:pointer-void</constant> -
+Points to a generic object.</para>
</listitem>
<listitem>
<para><constant>*</constant> - Used to declare a pointer to an object</para>
<refsect1>
<title>Examples</title>
<programlisting>
-(def-array ca :char)
+(def-array-pointer ca :unsigned-char)
(let ((fs (convert-to-foreign-string "ab")))
(values (null-char-p (deref-array fs 'ca 0))
(null-char-p (deref-array fs 'ca 2))))
<para>None.</para>
</refsect1>
</refentry>
+ </reference>
- <refentry id="ensure-char">
- <refnamediv>
- <refname>ensure-char</refname>
- <refpurpose>Ensures value is a character.
- </refpurpose>
- <refclass>Macro</refclass>
- </refnamediv>
- <refsynopsisdiv>
- <title>Syntax</title>
- <synopsis>
- <function>ensure-char</function> <replaceable>obj</replaceable> => <returnvalue>char</returnvalue>
- </synopsis>
- </refsynopsisdiv>
- <refsect1>
- <title>Arguments and Values</title>
- <variablelist>
- <varlistentry>
- <term><parameter>obj</parameter></term>
- <listitem>
- <para>A character or integer.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><parameter>char</parameter></term>
- <listitem>
- <para>A character value.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>Description</title>
- <para>
- Enscapsulates the fact that some implementations return a character
-and others return an integer when dereferencing a character pointer.
- </para>
- </refsect1>
- <refsect1>
- <title>Examples</title>
- <para>
-<programlisting>
-(let ((fs (convert-to-foreign-string "a")))
- (prog1
- (ensure-char (deref-pointer fs :char))
- (free-foreign-object fs)))
-=> #\a
-</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>Signals an error if <parameter>obj</parameter> is not
-an integer or character.</para>
- </refsect1>
- </refentry>
-</reference>
-
-<reference>
- <title>Aggregate Types</title>
+ <reference>
+ <title>Aggregate Types</title>
<partintro>
<title>Overview</title>
<para>
Aggregate types are comprised of one or more primitive types.
</para>
-</partintro>
+ </partintro>
- <refentry id="def-enum">
- <refnamediv>
- <refname>def-enum</refname>
+ <refentry id="def-enum">
+ <refnamediv>
+ <refname>def-enum</refname>
<refpurpose>Defines a &c; enumeration.
</refpurpose>
<refclass>Macro</refclass>
<refentry id="get-slot-value">
<refnamediv>
- <refname>def-slot-value</refname>
+ <refname>get-slot-value</refname>
<refpurpose>Retrieves a value from a slot of a structure.
</refpurpose>
<refclass>Macro</refclass>
</refentry>
- <refentry id="def-array">
+ <refentry id="def-array-pointer">
<refnamediv>
- <refname>def-array</refname>
- <refpurpose>Defines a foreign array type.
+ <refname>def-array-pointer</refname>
+ <refpurpose>Defines a pointer to a array of type.
</refpurpose>
<refclass>Macro</refclass>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>def-array</function> <replaceable>name type</replaceable>
+ <function>def-array-pointer</function> <replaceable>name type</replaceable>
</synopsis>
</refsynopsisdiv>
<refsect1>
<refsect1>
<title>Description</title>
<para>
- Defines a foreign array type.
+ Defines a type tat is a pointer to an array of type.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<programlisting>
-(def-array byte-array :unsigned-char)
+(def-array-pointer byte-array-pointer :unsigned-char)
</programlisting>
</refsect1>
<refsect1>
<refsect1>
<title>Examples</title>
<programlisting>
-(def-array ca :char)
+(def-array-pointer ca :char)
(let ((fs (convert-to-foreign-string "ab")))
(values (null-char-p (deref-array fs 'ca 0))
(null-char-p (deref-array fs 'ca 2))))
&t;
</programlisting>
</refsect1>
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ The TYPE argument is ignored for CL implementations other than
+ AllegroCL. If you want to cast a pointer to another type use
+ WITH-CAST-POINTER together with DEREF-POINTER/DEREF-ARRAY.
+ </para>
+ </refsect1>
<refsect1>
<title>Side Effects</title>
<para>None.</para>
<para>None.</para>
</refsect1>
</refentry>
+
+ <refentry id="def-union">
+ <refnamediv>
+ <refname>def-union</refname>
+ <refpurpose>Defines a foreign union type.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-union</function> <replaceable>name &rest fields</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A name of the new union type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>fields</parameter></term>
+ <listitem>
+ <para>A list of fields of the union.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Defines a foreign union type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <programlisting>
+(def-union test-union
+ (a-char :char)
+ (an-int :int))
+
+(let ((u (allocate-foreign-object 'test-union))
+ (setf (get-slot-value u 'test-union 'an-int) (+ 65 (* 66 256)))
+ (prog1
+ (ensure-char-character (get-slot-value u 'test-union 'a-char))
+ (free-foreign-object u)))
+=> #\A
+ </programlisting>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Defines a new foreign type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
</reference>
<reference>
<partintro>
<title>Overview</title>
<para>
- Objects are entities that can allocated and freed.
+ Objects are entities that can allocated, referred to by pointers, and
+can be freed.
</para>
</partintro>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>allocate-foreign-object</function> <replaceable>type</replaceable> => <returnvalue>ptr</returnvalue>
+ <function>allocate-foreign-object</function> <replaceable>type &optional size</replaceable> => <returnvalue>ptr</returnvalue>
</synopsis>
</refsynopsisdiv>
<refsect1>
<varlistentry>
<term><parameter>type</parameter></term>
<listitem>
- <para>A type of foreign object to allocate.
+ <para>The type of foreign object to allocate. This parameter is evaluated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>size</parameter></term>
+ <listitem>
+ <para>An optional size parameter that is evaluated. If specified, allocates and returns an
+array of <parameter>type</parameter> that is <parameter>size</parameter> members long. This parameter is evaluated.
</para>
</listitem>
</varlistentry>
</refentry>
- <refentry id="pointer-address">
+ <refentry id="with-foreign-object">
<refnamediv>
- <refname>pointer-address</refname>
- <refpurpose>Returns the address of a pointer.
+ <refname>with-foreign-object</refname>
+ <refpurpose>Wraps the allocation of a foreign object around a body of code.
</refpurpose>
<refclass>Macro</refclass>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>pointer-address</function> <replaceable>ptr</replaceable> => <returnvalue>address</returnvalue>
+ <function>with-foreign-object</function> <replaceable>(var type) &body body</replaceable> => <returnvalue>form-return</returnvalue>
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments and Values</title>
<variablelist>
<varlistentry>
- <term><parameter>ptr</parameter></term>
+ <term><parameter>var</parameter></term>
<listitem>
- <para>A pointer to a foreign object.
+ <para>The variable name to bind.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><parameter>address</parameter></term>
+ <term><parameter>type</parameter></term>
<listitem>
- <para>An integer representing the pointer's address.
+ <para>The type of foreign object to allocate. This parameter is evaluated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>form-return</returnvalue></term>
+ <listitem>
+ <para>The result of evaluating the <parameter>body</parameter>.
</para>
</listitem>
</varlistentry>
<refsect1>
<title>Description</title>
<para>
- Returns the address as an integer of a pointer.
+This function wraps the allocation, binding, and destruction of a foreign object.
+On &cmucl; and
+&lw; platforms the object is stack allocated for efficiency. Benchmarks show that &acl; performs
+much better with static allocation.
</para>
</refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <programlisting>
+(defun gethostname2 ()
+ "Returns the hostname"
+ (uffi:with-foreign-object (name '(:array :unsigned-char 256))
+ (if (zerop (c-gethostname (uffi:char-array-to-pointer name) 256))
+ (uffi:convert-from-foreign-string name)
+ (error "gethostname() failed."))))
+ </programlisting>
+ </refsect1>
<refsect1>
<title>Side Effects</title>
<para>None.</para>
</refsect1>
</refentry>
-
- <refentry id="deref-pointer">
+ <refentry id="size-of-foreign-type">
<refnamediv>
- <refname>deref-pointer</refname>
- <refpurpose>Deferences a pointer.
+ <refname>size-of-foreign-type</refname>
+ <refpurpose>Returns the number of data bytes used by a foreign object type.
</refpurpose>
<refclass>Macro</refclass>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>def-pointer</function> <replaceable>ptr type</replaceable> => <returnvalue>value</returnvalue>
+ <function>size-of-foreign-type</function> <replaceable>ftype</replaceable>
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments and Values</title>
<variablelist>
<varlistentry>
- <term><parameter>ptr</parameter></term>
- <listitem>
- <para>A pointer to a foreign object.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><parameter>type</parameter></term>
- <listitem>
- <para>A foreign type of the object being pointed to.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><parameter>value</parameter></term>
+ <term><parameter>ftype</parameter></term>
<listitem>
- <para>The value of the object where the pointer points.
+ <para>A foreign type specifier. This parameter is evaluated.
</para>
</listitem>
</varlistentry>
<refsect1>
<title>Description</title>
<para>
- Returns the object to which a pointer points.
+ Returns the number of data bytes used by a foreign object type. This does not include any Lisp storage overhead.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
<programlisting>
-(let ((fs (convert-to-foreign-string "a")))
- (prog1
- (ensure-char (deref-pointer fs :char))
- (free-foreign-object fs)))
-=> #\a
+(size-of-foreign-object :unsigned-byte)
+=> 1
+(size-of-foreign-object 'my-100-byte-vector-type)
+=> 100
</programlisting>
- </para>
+ </para>
</refsect1>
<refsect1>
<title>Side Effects</title>
<para>None.</para>
- </refsect1>
- <refsect1>
+ </refsect1> <refsect1>
<title>Affected by</title>
<para>None.</para>
</refsect1>
</refsect1>
</refentry>
- <refentry id="make-null-pointer">
+ <refentry id="pointer-address">
<refnamediv>
- <refname>make-null-pointer</refname>
- <refpurpose>Create a &null; pointer.
+ <refname>pointer-address</refname>
+ <refpurpose>Returns the address of a pointer.
</refpurpose>
<refclass>Macro</refclass>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>make-null-pointer</function> <replaceable>type</replaceable> => <returnvalue>ptr</returnvalue>
+ <function>pointer-address</function> <replaceable>ptr</replaceable> => <returnvalue>address</returnvalue>
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments and Values</title>
<variablelist>
<varlistentry>
- <term><parameter>type</parameter></term>
+ <term><parameter>ptr</parameter></term>
<listitem>
- <para>A type of object to which the pointer refers.
+ <para>A pointer to a foreign object.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><parameter>ptr</parameter></term>
+ <term><parameter>address</parameter></term>
<listitem>
- <para>The &null; pointer of type <parameter>type</parameter>.
+ <para>An integer representing the pointer's address.
</para>
</listitem>
</varlistentry>
<refsect1>
<title>Description</title>
<para>
- Creates a &null; pointer of a specified type.
+ Returns the address as an integer of a pointer.
</para>
</refsect1>
<refsect1>
</refentry>
- <refentry id="null-pointer-p">
+ <refentry id="deref-pointer">
<refnamediv>
- <refname>null-pointer-p</refname>
- <refpurpose>Tests a pointer for &null; value.
+ <refname>deref-pointer</refname>
+ <refpurpose>Deferences a pointer.
</refpurpose>
<refclass>Macro</refclass>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
<synopsis>
- <function>null-pointer-p</function> <replaceable>ptr</replaceable> => <returnvalue>is-null</returnvalue>
+ <function>deref-pointer</function> <replaceable>ptr type</replaceable> => <returnvalue>value</returnvalue>
</synopsis>
</refsynopsisdiv>
<refsect1>
<varlistentry>
<term><parameter>ptr</parameter></term>
<listitem>
- <para>A foreign object pointer.
+ <para>A pointer to a foreign object.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><returnvalue>is-null</returnvalue></term>
+ <term><parameter>type</parameter></term>
<listitem>
- <para>The boolean flag.
+ <para>A foreign type of the object being pointed to.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>value</returnvalue></term>
+ <listitem>
+ <para>The value of the object where the pointer points.
</para>
</listitem>
</varlistentry>
<refsect1>
<title>Description</title>
<para>
- A predicate testing if a pointer is has a &null; value.
+ Returns the object to which a pointer points.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+<programlisting>
+(let ((intp (allocate-foreign-object :int)))
+ (setf (deref-pointer intp :int) 10)
+ (prog1
+ (deref-pointer intp :int)
+ (free-foreign-object intp)))
+=> 10
+</programlisting>
</para>
</refsect1>
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ The TYPE argument is ignored for CL implementations other than
+ AllegroCL. If you want to cast a pointer to another type use
+ WITH-CAST-POINTER together with DEREF-POINTER/DEREF-ARRAY.
+ </para>
+ </refsect1>
<refsect1>
<title>Side Effects</title>
<para>None.</para>
</refsect1>
</refentry>
-
- <refentry id="null-cstring-pointer">
+ <refentry id="ensure-char-character">
<refnamediv>
- <refname>+null-cstring-pointer+</refname>
- <refpurpose>A constant &null; cstring pointer.
+ <refname>ensure-char-character</refname>
+ <refpurpose>Ensures that a dereferenced <constant>:char</constant> pointer is
+a character.
</refpurpose>
- <refclass>Constant</refclass>
+ <refclass>Macro</refclass>
</refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>ensure-char-character</function> <replaceable>object</replaceable> => <returnvalue>char</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>object</parameter></term>
+ <listitem>
+ <para>Either a character or a integer specifying a character code.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>char</returnvalue></term>
+ <listitem>
+ <para>A character.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
<refsect1>
<title>Description</title>
<para>
- A &null; cstring pointer. This can be used for testing
-if a cstring returned by a function is &null;.
+ Ensures that an objects obtained by dereferencing
+<constant>:char</constant> and <constant>:unsigned-char</constant>
+pointers are a lisp character.
</para>
</refsect1>
- </refentry>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+<programlisting>
+(let ((fs (convert-to-foreign-string "a")))
+ (prog1
+ (ensure-char-character (deref-pointer fs :char))
+ (free-foreign-object fs)))
+=> #\a
+</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>Depending upon the implementation and what &uffi; expects, this
+macro may signal an error if the object is not a character or
+integer.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ensure-char-integer">
+ <refnamediv>
+ <refname>ensure-char-integer</refname>
+ <refpurpose>Ensures that a dereferenced <constant>:char</constant> pointer is
+an integer.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>ensure-char-integer</function> <replaceable>object</replaceable> => <returnvalue>int</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>object</parameter></term>
+ <listitem>
+ <para>Either a character or a integer specifying a character code.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>int</returnvalue></term>
+ <listitem>
+ <para>An integer.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Ensures that an object obtained by dereferencing a
+<constant>:char</constant> pointer is an integer.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+<programlisting>
+(let ((fs (convert-to-foreign-string "a")))
+ (prog1
+ (ensure-char-integer (deref-pointer fs :char))
+ (free-foreign-object fs)))
+=> 96
+</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>Depending upon the implementation and what &uffi; expects, this
+macro may signal an error if the object is not a character or
+integer.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="make-null-pointer">
+ <refnamediv>
+ <refname>make-null-pointer</refname>
+ <refpurpose>Create a &null; pointer.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>make-null-pointer</function> <replaceable>type</replaceable> => <returnvalue>ptr</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A type of object to which the pointer refers.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>The &null; pointer of type <parameter>type</parameter>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Creates a &null; pointer of a specified type.
+ </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 id="null-pointer-p">
+ <refnamediv>
+ <refname>null-pointer-p</refname>
+ <refpurpose>Tests a pointer for &null; value.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>null-pointer-p</function> <replaceable>ptr</replaceable> => <returnvalue>is-null</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A foreign object pointer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>is-null</returnvalue></term>
+ <listitem>
+ <para>The boolean flag.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ A predicate testing if a pointer is has a &null; value.
+ </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 id="null-cstring-pointer">
+ <refnamediv>
+ <refname>+null-cstring-pointer+</refname>
+ <refpurpose>A constant &null; cstring pointer.
+ </refpurpose>
+ <refclass>Constant</refclass>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ A &null; cstring pointer. This can be used for testing
+if a cstring returned by a function is &null;.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="with-cast-pointer">
+ <refnamediv>
+ <refname>with-cast-pointer</refname>
+ <refpurpose>Wraps a body of code with a pointer cast to a new type.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>with-cast-pointer</function> (<replaceable>binding-name ptr type) & body body</replaceable> => <returnvalue>value</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A pointer to a foreign object.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A foreign type of the object being pointed to.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>value</returnvalue></term>
+ <listitem>
+ <para>The value of the object where the pointer points.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Executes BODY with POINTER cast to be a pointer to type TYPE. If
+ BINDING-NAME is provided the cast pointer will be bound to this
+ name during the execution of BODY. If BINDING-NAME is not provided
+ POINTER must be a name bound to the pointer which should be
+ cast. This name will be bound to the cast pointer during the
+ execution of BODY.
+
+ This is a no-op in AllegroCL but will wrap BODY in a LET form if
+ BINDING-NAME is provided.
+
+ This macro is meant to be used in conjunction with DEREF-POINTER or
+ DEREF-ARRAY. In Allegro CL the "cast" will actually take place in
+ DEREF-POINTER or DEREF-ARRAY.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+<programlisting>
+(with-foreign-object (size :int)
+ ;; FOO is a foreign function returning a :POINTER-VOID
+ (let ((memory (foo size)))
+ (when (mumble)
+ ;; at this point we know for some reason that MEMORY points
+ ;; to an array of unsigned bytes
+ (with-cast-pointer (memory :unsigned-byte)
+ (dotimes (i (deref-pointer size :int))
+ (do-something-with
+ (deref-array memory '(:array :unsigned-byte) i)))))))
+</programlisting>
+ </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 id="def-foreign-var">
+ <refnamediv>
+ <refname>def-foreign-var</refname>
+ <refpurpose>
+Defines a symbol macro to access a variable in foreign code
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-foreign-var</function> <replaceable>name type module</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>
+A string or list specificying the symbol macro's name. If it is a
+ string, that names the foreign variable. A Lisp name is created
+ by translating #\_ to #\- and by converting to upper-case in
+ case-insensitive Lisp implementations. If it is a list, the first
+ item is a string specifying the foreign variable name and the
+ second it is a symbol stating the Lisp name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A foreign type of the foreign variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>module</returnvalue></term>
+ <listitem>
+ <para>
+ A string specifying the module (or library) the foreign variable
+ resides in. (Required by Lispworks)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+Defines a symbol macro which can be used to access (get and set) the
+value of a variable in foreign code.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <refsect2>
+ <title>C code</title>
+<programlisting>
+ int baz = 3;
+
+ typedef struct {
+ int x;
+ double y;
+ } foo_struct;
+
+ foo_struct the_struct = { 42, 3.2 };
+
+ int foo () {
+ return baz;
+ }
+</programlisting>
+</refsect2>
+<refsect2>
+<title>Lisp code</title>
+<programlisting>
+ (uffi:def-struct foo-struct
+ (x :int)
+ (y :double))
+
+ (uffi:def-function ("foo" foo)
+ ()
+ :returning :int
+ :module "foo")
+
+ (uffi:def-foreign-var ("baz" *baz*) :int "foo")
+ (uffi:def-foreign-var ("the_struct" *the-struct*) foo-struct "foo")
+
+
+*baz*
+ => 3
+
+(incf *baz*)
+ => 4
+
+(foo)
+ => 4
+</programlisting>
+</refsect2>
+ </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>
<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 as parameters to and from functions. An implementation, such as CMUCL,
-may not convert these to a foreign type for efficiency sake. Thus, it is not
-possible to "allocate" a cstring. In contrast, foreign strings
-always need to have memory for them.
- </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:free-foreign-object name)
+ (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 id="convert-from-cstring">
</refsect1>
<refsect1>
<title>Side Effects</title>
- <para>None.</para>
+ <para>On some implementations, this function allocates memory.</para>
</refsect1>
<refsect1>
<title>Affected by</title>
<title>Description</title>
<para>
Frees any memory possibly allocated by
- <function>convert-to-cstring</function>.
+ <function>convert-to-cstring</function>. On some implementions, a cstring is just the Lisp string itself.
</para>
</refsect1>
<refsect1>
<refsect1>
<title>Description</title>
<para>
- Binds a lexical variable to a newly allocated <varname>cstring</varname>. Automatically frees <varname>cstring</varname>.
+ Binds a symbol to a cstring created from conversion of a string. Automatically frees the <varname>cstring</varname>.
</para>
</refsect1>
<refsect1>
<varlistentry>
<term><parameter>unsigned</parameter></term>
<listitem>
- <para>A boolean flag with a default value of &nil;. When true,
+ <para>A boolean flag with a default value of &t;. When true,
marks the pointer as an <constant>:unsigned-char</constant>.
</para>
</listitem>
<varlistentry>
<term><parameter>args</parameter></term>
<listitem>
- <para>A list of argument declarations. Use &nil; to specify no arguments.
+ <para>A list of argument declarations. If &nil;, indicates that the function does not take any arguments.
</para>
</listitem>
</varlistentry>
<term><returnvalue>returning</returnvalue></term>
<listitem>
<para>A declaration specifying the result type of the
-foreign function.
+foreign function. If <constant>:void</constant> indicates module does not return any value.
</para>
</listitem>
</varlistentry>
<title>Examples</title>
<programlisting>
(def-function "gethostname"
- ((name :cstring)
+ ((name (* :unsigned-char))
(len :int))
:returning :int)
</programlisting>
<refsect1>
<title>Syntax</title>
<synopsis>
- <function>load-foreign-library</function> <replaceable>filename &key module supporting-libraries</replaceable> => <returnvalue>success</returnvalue>
+ <function>load-foreign-library</function> <replaceable>filename &key module supporting-libraries force-load</replaceable> => <returnvalue>success</returnvalue>
</synopsis>
</refsect1>
<refsect1>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><parameter>force-load</parameter></term>
+ <listitem>
+ <para>Forces the loading of the library if it has been previously loaded.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><returnvalue>success</returnvalue></term>
<listitem>
<title>Description</title>
<para>Loads a foreign library. Applies a module name to functions
within the library. Ensures that a library is only loaded once during
-a session.
+a session. A library can be reloaded by using the <symbol>:force-load</symbol> key.
</para>
</refsect1>
<refsect1>
</refsect1>
</refentry>
+ <refentry id="find-foreign-library">
+ <refnamediv>
+ <refname>find-foreign-library</refname>
+ <refpurpose>Finds a foreign library file.
+ </refpurpose>
+ <refclass>Function</refclass>
+ </refnamediv>
+ <refsect1>
+ <title>Syntax</title>
+<synopsis>
+ <function>find-foreign-library</function> <replaceable>names directories & drive-letters types</replaceable> => <returnvalue>path</returnvalue>
+</synopsis>
+ </refsect1>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>names</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the base name of the library file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>directories</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the directory the library file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>drive-letters</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the drive letters for the library file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>types</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the file type of the library file. Default
+is &nil;. If &nil;, will use a default type based on the currently running implementation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>path</returnvalue></term>
+ <listitem>
+ <para>A path containing the path found, or &nil; if the library file was not found.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>Finds a foreign library by searching through a number of possible locations. Returns
+the path of the first found file.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <programlisting>
+(find-foreign-library '("libmysqlclient" "libmysql")
+ '("/opt/mysql/lib/mysql/" "/usr/local/lib/" "/usr/lib/" "/mysql/lib/opt/")
+ :types '("so" "dll")
+ :drive-letters '("C" "D" "E"))
+=> #P"D:\\mysql\\lib\\opt\\libmysql.dll"
+ </programlisting>
+ </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>