
4.1 The Foreign Function Interface
copy-foreign-pointer foreign-pointer&key :static :malloc :alignment
copy-foreign-pointer creates a new foreign pointer object of the same type as the specified argument and that points at a copy of the foreign storage pointed at by the argument.
:malloc keyword argument has a non-nil value, the storage is allocated by the functionmalloc-foreign-pointer.:alignment keyword argument is passed tomalloc-foreign-pointer. The default value of the:alignment keyword argument is 1.make-foreign-pointer allocates the storage.:static and the:alignment keyword arguments are passed tomake-foreign-pointer.
> (def-foreign-struct test
    (a :type :signed-32bit)
    (b :type :double-float))
TEST
> (setq *fp1* (make-test :a 99 :b 1.23))
#<Foreign-Pointer 79C028 (:POINTER TEST)>
> (test-a *fp1*)
99
> (test-b *fp1*)
1.23
> (setq *fp2* (copy-foreign-pointer *fp1*))
#<Foreign-Pointer 79C038 (:POINTER TEST)>
> (test-a *fp2*)
99
> (test-b *fp2*)
1.23
 make-foreign-pointer,
 Syntax:def-foreign-callable name-and-options ({arg-description}*){declaration | documentation}*{form}*
 name-and-options::= function-name| (function-name {option}*)
 option::= (:language language)| (:name foreign-name)| (:return-type return-type)
arg-description::= (arg-name foreign-type)
def-foreign-callable defines a Lisp function that can be called from a function defined by a language other than Lisp, that is, by a foreign function.
def-foreign-callable is a symbol that is specified by the function-name argument and that associates a foreign function name with a Lisp function name. Once the association is specified, you can use the foreign function to call the resulting Lisp function from outside Lisp.
:language language
:c, which is the default value. The Section 4.4 shows the call disciplines used when you pass foreign data to Lisp functions, and vice versa.
:name foreign-namedef-foreign-callable.
*lisp-symbol-to-foreign-string-method* is a function of two arguments, the function is called with the symbol and the language as arguments. If the function returns a string, that string is used as the symbol name.:return-type foreign-type
declare.
function.
def-foreign-callable must be evaluated before the foreign file is loaded with the functionload-foreign-file. If a foreign file is loaded before the applicabledef-foreign-callable forms have been evaluated (or have been loaded from a compiled file), you can use the functionreload-foreign-files to reload all foreign files and thus complete the necessary linkages. There is no order dependency on uses of the macrodef-foreign-function with the functionload-foreign-file.
; This example assumes that the file "callback.c" contains the
; following code, that this file has been compiled using
; "cc -c callback.c".
; 
; int c_function (value, string)
; int value;
; char *string;
; { 
;   return ( c_to_lisp_function(value, string) ) ;
; }
; Load the foreign-code.
> (load-foreign-files "callback.o")
  ;;; Loading foreign object file "callback.o"
  ;;; Reading library file "/usr/lib/libc.a"
  ;;; Reading library file "/tmp_mnt/net/cos2/sparccc/
  ;;; SUNWspro/SC2.0/cg89/libm.a"
  ;;; Reading library file "/usr/ucblib/libucb.a"
  ;;; Warning: The following foreign symbols are undefined: 
(c_to_lisp_function)
NIL
; Note that the foreign-function c_to_lisp_function is not yet 
; defined. You can define it from Lisp by using def-foreign-
; callable.
> (def-foreign-callable (c-to-lisp-function 
                          (:return-type :signed-32bit))
    ((value :signed-32bit) (string :simple-string))
  (print string)
  (* value 3))
C-TO-LISP-FUNCTION 
; Verify that c_to_lisp_function is now defined.
> (foreign-undefined-symbol-names)
NIL 
; Next define a way to call the foreign-function c_function from
; this is a test Lisp.
> (def-foreign-function (test-callback 
                          (:name "c_function")
                          (:return-type :signed-32bit))
   (value :signed-32bit) (string :simple-string))
TEST-CALLBACK
; Test the defined functions.
> (test-callback 23 "this is a test string")
"this is a test string" 
69
; To see what happened in more detail, trace #'print and #'*.
> (trace print *)
(PRINT *)
> (test-callback 23 "this is a test string")
1 Enter PRINT "this is a test string"
"this is a test string" 
1 Exit PRINT "this is a test string"
1 Enter * 23 3
1 Exit * 69
69
> (untrace)
(PRINT *)
 def-foreign-callable
 Syntax:def-foreign-function name-and-options {documentation}*{arg-description}*[&optional {arg-description}+][&rest {arg-description}+][&key {arg-description}+]
 name-and-options::= function-name|(function-name {option}*)
 option::= (:language language)|(:name foreign-name)|(:return-type return-type)|(:max-rest-args value)
 arg-description::= arg-name|(arg-name foreign-type)|((arg-name default-value) foreign-type)
def-foreign-function creates a Lisp function that calls a foreign function, or a function defined by a language other than Lisp. The macro converts Lisp arguments to the appropriate foreign data type before it calls the foreign function. The value returned by the foreign function is converted to a Lisp data type.
def-foreign-function create interpreted Lisp functions, and compiled calls create compiled Lisp functions.
def-foreign-function is a symbol that is specified by the function-name argument and that associates a Lisp function name with an appropriate foreign function name. Once the association is specified, you can use the resulting Lisp function to call the foreign function from within Lisp.
:language language:fortran,:c, or :pascal; the default value is:c. The Section 4.4 shows the calling conventions used when you pass foreign data to Lisp functions, and vice versa.
:name foreign-name
*lisp-symbol-to-foreign-string-method* is a function of two arguments, the function is called with the symbol and the language as arguments. If the function returns a string, that string is used as the symbol name.def-foreign-function is used.
:return-type foreign-type
:max-rest-args value&rest arguments that you can pass as arguments to the foreign function. The value that you specify must be an integer that is greater than or equal to 0 and that is less than or equal to the machine-specific limit for the number of arguments that a function can take; the machine-specific limit must be at least 100. The default value is 10. If the foreign function does not take&rest arguments, this option has no effect.
function.
&optional,&rest, or&key. You can list this argument with a default-value if you supply the optional argument foreign-type.
:arbitrary, which indicates that the coercion is based on the specified:language option.
:array,:string,:simple-string, and:simple-vector-type change the argument passed by the Lisp function.
f_init, which is defined in the FORTRAN libraries. But when you use isolated compiled FORTRAN functions, as in the Foreign Function Interface, you must explicitly perform the initialization. Thus, you should load the initialization function and evaluate it before evaluating the FORTRAN functions, as the following example shows:
> (def-foreign-function (f_init (:language :fortran) 
                                (:return-type :null)
                                (:name "f_init")))
F_INIT
> (load-foreign-libraries nil 
                          '("-lV77" "-lF77" "-lM77" "-lm" "-lc"))
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"+
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
 ;;; Reading library file "/usr/lib/libc.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a" 
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
 ;;; Reading library file "/usr/lib/libc.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
 ;;; Reading library file "/usr/lib/libc.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
 ;;; Reading library file "/usr/lib/libc.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
 ;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
 ;;; Reading library file "/usr/lib/libc.a"
T
> (f_init)
NIL
 with-static-area or symbols that have been freshly created in a package by the Common Lisp functionintern; note that the functionread calls intern. If dynamic data are passed to foreign functions, the results are unpredictable. See the reference page for stationary-object-p for more information.
;; In the first example, call a FORTRAN library function that
;; takes a string of length 24 and writes the current date in it.
> (def-foreign-function (fdate (:language :fortran) 
       (:return-type :null))
      (name :simple-string))
FDATE
> (load-foreign-libraries nil 
                          '("-lF77" "-lM77" "-lV77" "-lm" "-lc"))
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
;;; Reading library file "/usr/lib/libc.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
;;; Reading library file "/usr/lib/libc.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libF77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libM77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0.1/libV77.a"
;;; Reading library file "/opt/SUNWspro/SC2.0/cg89/libm.a"
;;; Reading library file "/usr/lib/libc.a"
T
> (setq date-string (with-static-area 
                      (make-string 24 :initial-element #\-)))
"------------------------"
> (fdate date-string)
NIL
> date-string
"Tue Jan  5 14:29:49 PST
;;; The next example uses Pascal.
> (def-foreign-function (pcos (:language :pascal)
                              (:name "cos")
                              (:return-type :double-float))
    (x :double-float))
> (load-foreign-libraries nil '("-lpc" "-lm"  "-lc"))
> (pcos pi)
;;; The last example shows how the Foreign Function Interface 
;;; works in C.
> (def-foreign-function (get-c-env (:name "getenv")
                                   (:return-type :simple-string))
    (name :pointer))
GET-C-ENV
> (setq name (malloc-foreign-pointer :type 
                                     '(:pointer (:array 
                                               :character (100)))))
#<Foreign-Pointer 6F7180 (:POINTER (:ARRAY :CHARACTER (100)))>
> (load-foreign-libraries nil '("-lm" "-lc"))
T
> (setf (foreign-string-value name) "SHELL")
"SHELL"
> (get-c-env name)
"/bin/csh"
> (setf (foreign-string-value name) "nonsense")
"nonsense"
> (get-c-env name)
NIL
 def-foreign-callable, load-foreign-files, stationary-object-p;with-static-area (in The User's Guide)
 Syntax:def-foreign-struct name-and-options {slot-decription}*
 name-and-options::= structure-name
 |(structure-name (:alignment alignment-info))
structure-name::= symbol
 alignment-info::= (:modulus value)|(:modulus value:remainder value)
 slot-description::= (slot-name:type slot-type-name)|(slot-name:type slot-type-name :overlays previous-slot-name)|(slot-name:type slot-type-name :offset value)
slot-name::= symbol
slot-type-name::= 1array-element-type-name|field-type-name
 array-element-type-name::=  primitive-array-element-type-name |previously-defined-structure-type-name|(:array array-element-type-name array-dimension-list)|(:array array-element-type-name array-dimension-list[array-discipline])
 primitive-array-element-type-name::= :character|:signed-8bit|:unsigned-8bit|:signed-16bit|:unsigned-16bit|:signed-32bit|:unsigned-32bit|:single-float|:double-float| (:[pointer slot-type-name)
 field-type-name::= (:field size position)|(:signed-field size position)|(:bit-field size position)|(:signed-bit-field size position)
 array-discipline::= :row-major|:column-major
def-foreign-struct defines structures within Lisp that are determined by other languages. Each structure has a fixed number of named components, which are called slots.
def-foreign-struct is a symbol that names the foreign structure. The following functions are automatically defined to operate on instances of the foreign structure:-p tests membership in the foreign structure type.setf with these access functions to destructively modify the contents of the slot.make-structure-name creates and returns new instances of the foreign structure type.:alignment keyword option. The symbol names the type of foreign structure being defined. The alignment-info argument to the keyword:alignment is a list of the following keywords and arguments::modulus keyword argument is an integer between 1 and 4095 inclusive. The default value is the least common multiple of the moduli for the slot types of the structure.:remainder keyword argument is an integer whose lowest value is 0 and whose highest value is 1 less than the value of the:modulus keyword argument. The default value is 0.:remainder argument modulo the:modulus argument.
:overlays keyword option as part of the slot-description argument if you want a slot to begin at the same machine address as a previously defined slot. The:offset keyword argument is any nonnegative fixnum; it specifies the number of bytes from the beginning address of the structure that are skipped over before the slot begins.
:overlays and:offset options::offset argument, you cannot use that slot as an:overlays argument.:offset argument must be consistent with the alignment requirements of the structure being defined and with the slot type.:overlays argument except for slots with specified offsets.:overlays argument for a slot whose alignment requirements are incompatible with the slot that it overlays.:field and:signed-field keyword options for field-type-name take two arguments. The size argument is a positive fixnum between 1 and 32 inclusive; there are 32 bits in a full machine word. The position argument is a nonnegative fixnum; the sum of the value specified for this argument and the value of the size argument must not exceed 32.
:bit-field and:signed-bit-field keyword options are like the:field and:signed-field options, except that a:bit-field type fits into the smallest possible number of bytes. That is, the foreign type size of:bit-field or:signed-bit-field is(ceiling (+ type position) bits-per-byte).
:array keyword option is used to make a recursive reference to the array element type specified as its first argument. Its second argument, array-dimension-list, is a list of nonnegative integers that specify the size of each of the dimensions of the array. The default value of the array-discipline argument is:row-major; in Common Lisp, the elements of a multidimensional array are stored in row-major order.
> (def-foreign-struct (example-struct 
                     (:alignment (:modulus 4 :remainder 2)))
    (slot-a :type :unsigned-32bit)
    (slot-b :type :signed-16bit))
EXAMPLE-STRUCT
 def-foreign-synonym-type, foreign-value, free-foreign-pointer, make-foreign-pointer, malloc-foreign-pointer, foreign-aref, typed-foreign-aref, undefine-foreign-type
def-foreign-synonym-type atomic-type-name previously-defined-type-name
def-foreign-synonym-type creates a synonym type for a previously defined type; that is, it associates a new name with an existing type.
;;; This example makes the symbol 'test-array a synonym for the ;;; list '(:array :character (2 3 4) :column-major).> (def-foreign-synonym-type test-array (:array :character (2 3 4) :column-major)) #<Foreign-Type (:ARRAY :CHARACTER (2 3 4) :COLUMN-MAJOR) 9B5D06>
; The following examples use the :enumeration, :set, and :packed- ; array foreign types, which correspond to Pascal data types.
> (def-foreign-synonym-type primary_colors (:enumeration (red yellow blue))) #<Foreign-Type (:ENUMERATION (RED YELLOW BLUE)) 9B774E>
> (setq color1 (make-foreign-pointer :type '(:pointer primary_colors))) #<Foreign-Pointer 75005C (:POINTER PRIMARY_COLORS)>
> (foreign-value color1) RED
> (symbol-value 'red) 0
> (def-foreign-synonym-type grades-type (:set :character)) #<Foreign-Type (:SET :CHARACTER) 9B896E>
> (setq grade1 (make-foreign-pointer :type '(:pointer grades-type))) #<Foreign-Pointer 750064 (:POINTER GRADES-TYPE)>
> (setf (foreign-value grade1) '(#\A #\B #\C #\D #\E #\F)) (#\A #\B #\C #\D #\E #\F)
> (foreign-value grade1) (#\A #\B #\C #\D #\E #\F)
> (def-foreign-synonym-type packed-array-3 (:packed-array 3 (10))) #<Foreign-Type (:PACKED-ARRAY (:FIELD 3 0) (10)) 9B98CE>
undefine-foreign-type
defined-foreign-type-p type-name
defined-foreign-type-p is true if the type-name argument specifies a currently defined foreign type; otherwise, it is false.
> (def-foreign-struct test-type (slot-1 :type :signed-32bit)) TEST-TYPEforeign-aref> (defined-foreign-type-p 'test-type) T
 Function
foreign-aref foreign-vector&rest indices
typed-foreign-aref foreign-type foreign-vector&rest indices
foreign-aref andtyped-foreign-aref provide Lisp access to arrays that are defined in other languages.
typed-foreign-aref also checks that the foreign array is of the specified type.
typed-foreign-aref is an optimized version offoreign-aref that provides access as fast as the Common Lisp functionaref when the array type has been declared. You must use the production mode of the Compiler to benefit from this optimization.
:array. You can create the foreign pointer with the functionsmake-foreign-pointer,malloc-foreign-pointer, or by combining the primitive type:pointer with the primitive type:array.
typed-foreign-aref is a previously defined foreign type. It can be one of the predefined types listed in Section 4.3, or any type derived from a predefined type. It is an error if the foreign-vector argument is not of the type specified in the foreign-type argument.
setf with these functions to destructively modify a foreign array element. An error is signaled if you attempt to set the foreign array element to a value that is illegal for its type.
(def-foreign-synonym-type array-example-type 
      (:pointer (:array :signed-16bit (10))))
#<Foreign-Type (:POINTER (:ARRAY :SIGNED-16BIT (10))) 9BAF26>
> (setq example-array (make-foreign-pointer 
                   :type 'array-example-type))
#<Foreign-Pointer 75008C (:POINTER (:ARRAY :SIGNED-16BIT (10)))>
> (dotimes (i 10) (setf (foreign-aref example-array i) i))
NIL
> (foreign-aref example-array 4)
4
> (typed-foreign-aref 'array-example-type example-array 7)
7
 foreign-pointer-address Function foreign-type-remainder Function
foreign-pointer-address foreign-pointer
foreign-pointer-p foreign-pointer
foreign-pointer-type foreign-pointer
foreign-typep foreign-pointer foreign-type
foreign-type-modulus foreign-type
foreign-type-remainder foreign-type
foreign-type-size foreign-type
foreign-pointer-address,foreign-pointer-p,foreign-pointer-type, andforeign-typep return information about the specified foreign pointer.
foreign-type-modulus,foreign-type-remainder, andforeign-type-size return information about the specified foreign type.
:pointer.
foreign-pointer-address returns the integer starting address of the object being pointed at by the foreign-pointer argument. You can use the Common Lisp macrosetf with this function to destructively modify the address of the object being pointed at.
foreign-pointer-p is true if its foreign-pointer argument is of type :pointer; otherwise, it is false.
foreign-pointer-type returns the type of the foreign-pointer argument. You can use the Common Lisp macrosetf with this function to destructively modify the foreign-pointer argument.
foreign-typep is true if the foreign-pointer argument is of the specified type; otherwise, it is false.
foreign-type-modulus returns the alignment modulus of the specified foreign type. The functionforeign-type-remainder returns the alignment remainder of the specified foreign type. Foreign types that use alignment are constructed to start at a machine address that is congruent to the alignment remainder modulo the alignment modulus.
foreign-type-size returns the unit size of the specified foreign type.
> (setq example-pointer (make-foreign-pointer 
                          :type '(:pointer :signed-32bit)))
#<Foreign-Pointer 7500AC (:POINTER :SIGNED-32BIT)>
> (foreign-pointer-address example-pointer)
7667884
> (foreign-pointer-p example-pointer)
T
> (foreign-pointer-type example-pointer)
#<Foreign-Type (:POINTER :SIGNED-32BIT) 9BD236>
> (foreign-typep example-pointer '(:pointer :signed-32bit))
T
> (foreign-type-modulus :unsigned-8bit)
1
> (foreign-type-remainder :unsigned-8bit)
0
> (foreign-type-size :unsigned-8bit)
1
 def-foreign-struct
foreign-size-of foreign-pointer-or-type
foreign-size-of returns an integer value whose meaning depends on the specified argument:foreign-type-size.
my-type is the name of a foreign type such that the value returned by the functionforeign-type-size formy-type is 12. Assume also thatmy-type-pointer is of type(:pointer my-type). In this case, the value returned byforeign-size-of for bothmy-type and formy-type-pointer is 12.
(:pointer my-type) is 4, not 12. In other words, even though the value returned by(foreign-pointer-type my-type-pointer) is a type whose name is'(:pointer my-type), the type of the foreign pointer object is not the type of the foreign storage that the object points at.
foreign-type-size
foreign-string-value foreign-pointer
foreign-string-value returns a copy of the string pointed at by the specified foreign pointer.
:pointer and must point to a character object or an array of character objects.
setf with this function to modify the string pointed at by the foreign-pointer argument.
;;; This example assumes that the file "string-test.c" contains 
;;; the following code and that this file has been compiled using
;;; "cc -c string-test.c".
;;;
;;; char *test_string = "This is a test-string.";
;;; char *string_function ()
;;; { 
;;;   return ( test_string );
;;; }
;; Load the foreign-code.
>  (load-foreign-files "string-test.o")
  ;;; Loading foreign object file "string-test.o"
T 
;; Define a function to look at the test-string.
> (def-foreign-function 
   (string-function (:return-type :simple-string)))
STRING-FUNCTION
> (string-function)
"This is a test-string." 
;; Define another foreign function that calls the same code to
;; return a foreign-pointer of type (:pointer :character).
> (def-foreign-function (string-function-2 
                           (:name "string_function")
                           (:return-type (:pointer :character))))
STRING-FUNCTION-2
> (setq str-ptr (string-function-2))
#<Foreign-Pointer 6DC958 (:POINTER :CHARACTER)>
;; The foreign value "str-ptr" points at the C string
;; "test_string".
> (foreign-string-value str-ptr)
"This is a test-string."
;; You can change the string if you are careful to put in another 
;; string of length at most that of the original one; this change 
;; is then reflected in the foreign function #'string-function.
> (setf (foreign-string-value str-ptr) "This is a changed
       string.")
"This is a changed string."
> (foreign-string-value str-ptr)
"This is a changed string."
> (string-function)
"This is a changed string."
;;; The value returned by FOREIGN-STRING-VALUE depends on the 
;;; type of the object being pointed at. If the foreign pointer 
;;; points to a character, FOREIGN-STRING-VALUE copies the 
;;; foreign characters, starting at the one pointed to, into a 
;;; Lisp string.  If the foreign pointer points to an array of 
;;; characters, FOREIGN-STRING-VALUE copies all the characters 
;;; in the foreign array into a Lisp string.  The result of using
;;; SETF with FOREIGN-STRING-VALUE depends on the foreign 
;;; pointer's type similarly.  The following example demonstrates
;;; this difference.  It first creates and initializes a foreign
;;; array of characters and two foreign pointers that refer to it.
> (setq array-8 (malloc-foreign-pointer
                  :type '(:pointer (:array :character (8)))))
#<Foreign-Pointer 6F6090 (:POINTER (:ARRAY :CHARACTER (8)))>
> (setq array-4 (make-foreign-pointer
                   :type '(:pointer (:array :character (4)))
                   :address (foreign-pointer-address array-8)))
#<Foreign-Pointer 6F6090 (:POINTER (:ARRAY :CHARACTER (4)))>
> (setf (foreign-string-value array-8) "12345678")
"12345678"
;; The function treats array-8 differently from array-4.
> (foreign-string-value array-8)
"12345678"
> (foreign-string-value array-4)
"1234"
;; Using SETF with FOREIGN-STRING-VALUE manipulates the foreign 
;; storage referred to by these two pointers differently.
> (setf (foreign-string-value array-4) "abcd")
"abcd"
> (foreign-string-value array-8)
"abcd5678"
;; Since FOREIGN-STRING-VALUE always uses the whole character 
;; array, the result of the following expressions is not 
;; surprising.  This property is used to null-terminate the
;; foreign sequence of characters returned by MALLOC-FOREIGN-
;; STRING as defined in the example in 
;; Section 4.1.1
>  (setf (foreign-string-value array-8) "A")
"A"
> (foreign-string-value array-8)
"A^@^@^@^@^@^@^@"
;; Now that the character array pointed to by both of these
;; foreign pointers can be treated as a null-terminated sequence
;; of characters, define a foreign pointer that does so.
> (setq char-seq (make-foreign-pointer
                   :type '(:pointer :character)
                   :address (foreign-pointer-address array-8)))
#<Foreign-Pointer 6F6090 (:POINTER :CHARACTER)>
> (foreign-string-value char-seq)
"A"
;; Note that using SETF with FOREIGN-STRING-VALUE on (:pointer
;; :character) overwrites null bytes.  You must ensure that the 
;; foreign storage referred to has enough space for the new value.
> (setf (foreign-string-value char-seq) "12345")
"12345"
> (foreign-string-value array-8)
"12345^@^@^@"
 foreign-undefined-symbol-names Function
foreign-undefined-symbol-names
foreign-undefined-symbol-names returns a list of the names of foreign symbols that are not currently associated with any foreign code or data.
;; Note that there are NO undefined foreign symbols. > (foreign-undefined-symbol-names) NIL;; Create an undefined foreign symbol. > (def-foreign-function (foreign-undefined-function (:name "JUNK-FUNCTION"))) FOREIGN-UNDEFINED-FUNCTION
> (foreign-undefined-symbol-names) ("JUNK-FUNCTION")
;; Get rid of the undefined foreign symbol. > (unintern-foreign-symbol "JUNK-FUNCTION") T
> (foreign-undefined-symbol-names) NIL
unintern-foreign-symbol
foreign-value foreign-pointer
foreign-value evaluates its foreign-pointer argument as follows:setf with this function to destructively modify the value pointed at by the foreign-pointer argument.
> (setq example-pointer 
        (make-foreign-pointer :type '(:pointer :signed-32bit)))
#<Foreign-Pointer 7500BC (:POINTER :SIGNED-32BIT)>
> (setf (foreign-value example-pointer) -123)
-123
> (foreign-value example-pointer)
-123
;;; The :bit-field type is similar to the :field type, except that
;;; the foreign type size of a :bit-field type is
;;; (ceiling (+ <size> <position>) <bits-per-byte>).
> (setq fp-bit-field (make-foreign-pointer
                       :type '(:pointer (:bit-field 13 3))))
#<Foreign-Pointer 79C038 (:POINTER (:BIT-FIELD 13 3))>
> (setq fp-16bit (make-foreign-pointer
                 :type '(:pointer :unsigned-16bit)
                 :address (foreign-pointer-address fp-bit-field)))
#<Foreign-Pointer 79C038 (:POINTER :UNSIGNED-16BIT)>
> (setf (foreign-value fp-bit-field) 1234)
1234
> (foreign-value fp-bit-field)
1234
> (foreign-value fp-16bit)
9872
> (ldb (byte 13 3) (foreign-value fp-16bit))
1234
> (foreign-type-size '(:bit-field 13 3))
2
 make-foreign-pointer, malloc-foreign-pointer
 Function foreign-variable-address Function
 foreign-variable-pointer Function
foreign-variable-p string
foreign-variable-address string
foreign-variable-pointer string
foreign-variable-p,foreign-variable-address, and foreign-variable-pointer return information about the active global foreign variable with the name specified in the string argument. A foreign variable is foreign storage that has a name.foreign-variable-p is true if an active global foreign variable with the specified name exists; otherwise, it is false.foreign-variable-address returns the integer starting address of the active global foreign variable with the specified name.foreign-variable-pointer returns the foreign pointer that points at the active global foreign variable with the specified name."var" for C variables namedvar"var_" for FORTRAN variables namedvardisksave, foreign pointers returned by the functionforeign-variable-pointer are preserved.
;; The foreign variable "write" is a Unix system-call. > (foreign-variable-p "write") :TEXT> (foreign-variable-address "write") 6315640
> (foreign-variable-pointer "write") #<Foreign-Pointer write 605E78>
;;; UNIX system calls that fail set errno to an error-specific ;;; positive integer; they do not clear it if no error occurs and ;;; instead indicate that an error has occurred with an otherwise ;;; impossible return value, usually -1. The values of errno are ;;; described in INTRO(2) and <errno.h> in the UNIX manual pages ;;; (usually available on line); each system call description ;;; mentions the errors that it can encounter. The following Lisp ;;; code manipulates the foreign variable errno.
;; Rather than create a new foreign pointer every time errno is ;; accessed, reuse a foreign pointer to errno.
> (let ((errno-ptr (foreign-variable-pointer "errno"))) ;; The Lisp function errno returns the current value of the ;; foreign variable errno. (defun errno () (foreign-value errno-ptr)) ;; The function reset-errno changes the value of the foreign ;; variable errno. By default, it resets the value to 0. It ;; returns errno's previous value. (defun reset-errno (&optional (n 0)) (check-type n unsigned-byte) (prog1 (foreign-value errno-ptr) (setf (foreign-value errno-ptr) n))) ) RESET-ERRNO
;;; UNIX also provides sys_errlist, a vector of message strings ;;; that describes the possible values of errno. The foreign ;;; variable sys_nerr contains the number of entries in this ;;; vector.
;; Again, rather than create a new foreign pointer every time the ;; message string vector is accessed, the foreign pointers are ;; reused. > (let* ((sys_nerr (foreign-value (make-foreign-pointer :type '(:pointer :signed-32bit) :address (foreign-variable-address "sys_nerr")))) (error-strings (make-foreign-pointer :type '(:pointer (:array (:pointer :character) (,sys_nerr))) :address (foreign-variable-address "sys_errlist")))) ;; Like the Lisp interface to errno that was defined ;; previously, the Lisp interface to the sys_errlist that is ;; being defined is different from the UNIX interface. The ;; function sys_errlist returns a Lisp string describing the ;; error-code, which defaults to the most recent UNIX error. ;; If error-code is not in the foreign variable sys_errlist, ;; the Lisp function returns "Unknown error"; this behavior ;; mirrors that of the LIBC function PERROR(3), which is used ;; to print error messages. (Since PERROR(3) does I/O, it ;; should not be used from Lisp.) (defun sys_errlist (&optional (error-code (errno))) (check-type error-code unsigned-byte) (if (< error-code sys_nerr) (foreign-string-value (foreign-aref error-strings error-code)) "Unknown error")) ) SYS_ERRLIST
;;; First clear any residual errors and see what the error message ;;; for no error is. > (reset-errno) 22
> (sys_errlist) "Error 0"
;; Now cause an error by using the STAT function defined in ;; Section 4.1.4 > (stat "there is no file with this name") NIL
> (sys_errlist) "No such file or directory"
> (errno) 2
foreign-undefined-symbol-names
 Function
free-foreign-pointer foreign-pointer
free-foreign-pointer uses the library function"free" to free the foreign storage being pointed at by the specified foreign pointer; the foreign pointer must have been created with the functionmalloc-foreign-pointer.
"malloc" at any time.
:pointer.
malloc-foreign-pointer
 Variable
*lisp-symbol-to-foreign-string-method*
*lisp-symbol-to-foreign-string-method* is used by the macrosdef-foreign-callable anddef-foreign-function in the following cases::name keyword option in the foreign function definition:name keyword option with a symbol in the foreign function definitionnil or a function of two arguments, the Lisp symbol and the foreign language. The function can be invoked to compute a name for a foreign function that was not named when defined.
:name keyword option, one of the following conversions takes place:*lisp-symbol-to-foreign-string-method* is a function of two arguments, the function is called with the symbol and the language as arguments. If the function returns a string, that string is used as the symbol name.nil, the default symbol name is translated into a form that the foreign language can understand. The Lisp symbol name is lowercased, dashes in the name are converted to underbar characters, and an underbar prefix or suffix is added if appropriate.;; To control the C foreign names of the Lisp functions #'test1, ;; #'test2, and #'test3, first check that there are no undefined ;; foreign symbols. > (foreign-undefined-symbol-names) NIL> (defun my-lisp-to-foreign-names (lisp-symbol language) (when (eq language :C) (cdr (assq lisp-symbol '((test1 . "my_test_1") (test2 . "my_test_2") (test3 . "my_test_3")))))) MY-LISP-TO-FOREIGN-NAMES
> (setq *lisp-symbol-to-foreign-string-method* #'MY-LISP-TO-FOREIGN-NAMES) #<Interpreted-Function (NAMED-LAMBDA MY-LISP-TO-FOREIGN-NAMES ...) 9CF51E>
> (def-foreign-function test2) TEST2
> (foreign-undefined-symbol-names) ("my_test_2")
> (def-foreign-function test47) TEST47
;; The function #'test2 used the new method, while #'test47 ;; did not. > (foreign-undefined-symbol-names) ("test47" "my_test_2")
;; Get rid of these "test" undefined foreign symbols. > (dolist (x (foreign-undefined-symbol-names)) (unintern-foreign-symbol x)) NIL
def-foreign-callable, def-foreign-function
 Function
load-foreign-files files&optional libraries
load-foreign-files loads foreign language compiled (.o) files into Lisp.
"-lc" "-lm" "-lucb" ); that is, the loader automatically searches the C, math run-time, and VCB compatibility libraries.
"-lc" in the list.
"-lF77","-lM77", and"-lV77" along with the C libraries"-lc" and"-lm".
"-lpc" with the C libraries"-lc" and"-lm".
 def-foreign-function.
;;; This example assumes that the file "string-test.c" contains ;;; code defining "string_function" and "test_string" and that it ;;; has been compiled using "cc -c string-test.c". ;; This single file can be loaded as follows: > (load-foreign-files "string-test.o") ;;; Loading foreign object file "string-test.o" T;; A single file can also be loaded by including the name in a ;; list. All loads involving more than one file must be done in ;; this way. > (load-foreign-files '("string-test.o")) ;;; Loading foreign object file "string-test.o" T
load-foreign-libraries
 Function
load-foreign-libraries strings&optional libraries
load-foreign-libraries loads functions from foreign language compiled library (.a) files into Lisp.
"fn" for C functions namedfn, and"fn_" for FORTRAN functions namedfn. Such functions are then called from Lisp with the namefn. Symbols that have been defined bydef-foreign-function ordef-foreign-struct since the last load are loaded automatically and should not be specified here. The strings argument is provided for backward compatibility withforeign-load-libraries; it should normally benil.
"-lc" "-lm"); that is, the loader automatically searches the C and math run-time libraries. If you wish to search other libraries as well as the C run-time library, you must include"-lc" in the list.
"-lF77","-lM77", and"-lV77" along with the C libraries"-lc" and"-lm".
"-lpc" with the C libraries"-lc" and"-lm".
;; When loading foreign libraries for FORTRAN code,   
;; use the following arguments:
> (load-foreign-libraries nil '("-lV77" "-lF77" "-lM77" "-lm" 
"-lc"))
T
;; When loading foreign libraries for C code, 
;; use the following arguments:
> (load-foreign-libraries nil '("-lm" "-lc"))
T
;; When loading foreign libraries for Pascal code, 
;; use the following arguments:
> (load-foreign-libraries nil '("-lpc" "-lm"  "-lc"))
T
 load-foreign-files
 Function
make-foreign-pointer &key :address :type :static :alignment
make-foreign-pointer makes a foreign pointer object of the specified type that points at a specified address. If you do not specify an address, an appropriate amount of foreign storage is allocated to hold the object that is pointed at.
make-foreign-pointer accepts the following keyword arguments; note that you must specify either the:address or:type keyword argument::address
:type
:staticnil value, the foreign storage that is created is preserved in any image that you save by invoking the functiondisksave; the value pointed to by the foreign pointer is not reinitialized when the saved image is started up. If the value of this keyword argument isnil, foreign storage is not preserved when you save the image; this value is the default.
:alignmentM and remainder R, the foreign pointer object that is created points to foreign storage with a base address that is congruent toR modulo the least common multiple ofM and the:alignment keyword argument. The default value of this argument is 1.
make-foreign-pointer will not be reclaimed. If you want the space to be recovered later and do not needmake-foreign-pointer's:address and:static functionality, usemalloc-foreign-pointer.
> (setq example-pointer (make-foreign-pointer 
                          :type '(:pointer :signed-32bit)))
#<Foreign-Pointer 7500CC (:POINTER :SIGNED-32BIT)>
 foreign-value, malloc-foreign-pointer
 Function
malloc-foreign-pointer &key :type :alignment
malloc-foreign-pointer makes a foreign pointer object of the specified type by using the library function"malloc"; it returns foreign storage. The functionfree-foreign-pointer frees any foreign storage returned by this function.
malloc-foreign-pointer accepts the following keyword arguments::type
:alignmentM and remainderR, the foreign pointer object that is created points to foreign storage with a base address that is congruent toR modulo the least common multiple ofM and the:alignment keyword argument. The default value of this argument is 1.
make-foreign-pointer and specifying only the:type keyword argument. Note that space used bymalloc-foreign-pointer will be reclaimed. If you do not need the space to be recovered later and do needmake-foreign-pointer's:address and:static functionality, usemake-foreign-pointer.
disksave.
;; Define a synonym type for an array of signed 16-bit integers.
> (def-foreign-synonym-type array-example-type
      (:pointer (:array :signed-16bit (10))))
#<Foreign-Type (:POINTER (:ARRAY :SIGNED-16BIT (10))) 9BB196>
;; Malloc a foreign array, set its contents, and examine one
;; entry.
> (setq example-array (malloc-foreign-pointer :type 'array-example-type))
#<Foreign-Pointer 6F50C0 (:POINTER (:ARRAY :SIGNED-16BIT (10)))>
> (dotimes (i 10) (setf (foreign-aref example-array i) i))
NIL
> (foreign-aref example-array 4)
4
;; Now free the foreign storage occupied by the array.
> (free-foreign-pointer example-array)
NIL
;; Malloc two more foreign arrays; notice the address of example-
;; array-1 is the same as that of example-array (which was just 
;; freed), while the address of example-array-2 is different.
> (setq example-array-1 (malloc-foreign-pointer :type 'array-
            example-type))
#<Foreign-Pointer 6F50A0 (:POINTER (:ARRAY :SIGNED-16BIT (10)))>
> (setq example-array-2 (malloc-foreign-pointer :type 'array-
            example-type))
#<Foreign-Pointer 6F50C0 (:POINTER (:ARRAY :SIGNED-16BIT (10)))>
> (dotimes (i 10) (setf (foreign-aref example-array-1 i) 
            (+ i 20)))
NIL
> (dotimes (i 10) (setf (foreign-aref example-array-2 i) i))
NIL
> (foreign-aref example-array-1 4)
24
> (foreign-aref example-array-2 4)
4
> (foreign-aref example-array 4)
4
> (free-foreign-pointer example-array-1)
NIL
> (free-foreign-pointer example-array-2)
NIL
 free-foreign-pointer, make-foreign-pointer
 Function
stationary-object-p lisp-object
stationary-object-p returns a non-nil value if the specified Lisp object does not move during a garbage collection; otherwise, it returnsnil.
Note: All modifiable Lisp data that are passed to a foreign function must be stationary. Examples of stationary data include data that have been allocated within a call to the macrowith-static-area or symbols that have been freshly created in a package by the Common Lisp functionintern; note that the functionread callsintern. If dynamic data are passed to foreign functions, the results are unpredictable.
def-foreign-struct or by invoking the functionmake-foreign-pointer without specifying the:address keyword argument, the foreign storage is always stationary and writable. Thus, you can always safely pass foreign pointers of type:arbitrary or :pointer to foreign functions.
;; Make two vectors, v and stationary-v; the first is not ;; stationary, while the second, created using the macro ;; with-static-area, is stationary. > (setq v (make-array 10)) #<Simple-Vector T 10 9DD086>undefine-foreign-type> (stationary-object-p v) NIL
> (setq stationary-v (with-static-area (make-array 10))) #<Simple-Vector T 10 8A0F7E>
> (stationary-object-p stationary-v) T
;; Since 'format is an interned symbol, it is stationary. ;; So is its symbol function. > (stationary-object-p 'format) T
> (stationary-object-p #'format) T
 Function
undefine-foreign-type foreign-type-name
undefine-foreign-type removes the name of a foreign type from the internal list of defined types.
> (def-foreign-synonym-type renamed-signed-32bit :signed-32bit) #<Foreign-Type :SIGNED-32BIT 6E6D6E>> (undefine-foreign-type 'renamed-signed-32bit) RENAMED-SIGNED-32BIT
def-foreign-struct, def-foreign-synonym-type
 Function
unintern-foreign-symbol symbol-name
unintern-foreign-symbol makes a foreign symbol inaccessible for general use. You can reuse the name of the uninterned symbol in newly loaded foreign object code without changing previously loaded code.
"sym" for C symbols namedsym"sym_" for FORTRAN symbols namedsymdef-foreign-function with names of symbols that you have uninterned with this function.
;; This form uninterns all undefined foreign symbols.
> (dolist (x (foreign-undefined-symbol-names)) 
    (unintern-foreign-symbol x))
NIL
 foreign-undefined-symbol-names
 Function
writable-object-p lisp-object
writable-object-p returns a non-nil value if the specified Lisp object can be written; otherwise, it returnsnil.
;; Make two vectors, v and stationary-v; the first is not ;; stationary, while the second, created using the macro ;; with-static-area, is stationary. They are both writable. > (setq v (make-array 10)) #<Simple-Vector T 10 9DEF5E>> (stationary-object-p v) NIL
> (setq stationary-v (with-static-area (make-array 10))) #<Simple-Vector T 10 8A0FC6>
> (stationary-object-p stationary-v) T
> (writable-object-p stationary-v) T
> (writable-object-p v) T
;; Since 'format is an interned symbol, it is stationary. So is ;; its symbol function. The symbol 'format is writable (although ;; it is necessary to be VERY careful when writing on a Lisp ;; symbol from foreign code), but the symbol function for 'format ;; is not.
> (stationary-object-p 'format) T
> (stationary-object-p #'format) T
> (writable-object-p 'format) T
> (writable-object-p #'format) NIL
 
 
 
 
 
Generated with Harlequin WebMaker