Defines a Lisp function to access a variable in foreign code.
fli
define-foreign-variable the-name &key type accessor language no-check module => lisp-name
the-name ::= lisp-name | (lisp-name foreign-name [encoding])
encoding ::= :source | :object | :lisp | :dbcs
accessor ::= :value | :address-of | :read-only | :constant
language ::= :c | :ansi-c
the-name |
Names the Lisp function which is used to access the foreign variable. |
type⇩ |
The FLI type corresponding to the type of the foreign variable to which Lisp is interfacing. The default is :int . |
language⇩ |
The language in which the foreign source code for the variable is written. The default is :ansi-c . |
no-check⇩ |
A boolean. |
module⇩ |
A string or symbol naming the module in which the foreign variable is defined. |
lisp-name⇩ |
A symbol naming the Lisp accessor. |
foreign-name⇩ |
A string or a symbol specifying the foreign name of the variable. |
lisp-name |
A symbol naming the Lisp accessor. |
The macro define-foreign-variable
defines a Lisp accessor lisp-name which can be used to get and set the value of a variable defined in foreign code.
accessor specifies what kind of accessor is generated for the variable. It can be one of the following:
:value |
The value of the foreign variable is returned directly and is the default when type is a non-aggregate type. If type is an aggregate type, then a copy of the object is allocated using allocate-foreign-object, and the copy is returned. In general, it is more useful to use accessor :address-of for aggregate types, to allow the original aggregate to be updated. |
:address-of |
Returns an FLI pointer pointing to the foreign variable. |
:read-only |
Ensures that no setf expander is defined for the variable, which means that its value can be read, but it cannot be set. |
:constant |
Is like :read-only and will return a constant value. For example, this is more efficient for a variable that always points to the same string. |
If the foreign variable has a type corresponding to an FLI aggregate type, then accessor must be supplied (there is no default).
encoding controls how the Lisp variable name is translated to match the foreign variable name in the foreign DLL. encoding can be one of the following:
:source | |
:object | |
:lisp | |
:dbcs |
Modifies the variable name on Windows, as described for define-foreign-function. |
If no-check is nil
, then the type of the value is provided to the setf expander for lisp-name is compared with type and an error is raised if it does not match. If no-check is t
then this check is not done and the effect will be undefined if the type does not match. If the compilation safety level is set to 0 then no-check defaults to t
, otherwise it defaults to nil
.
If you specify any of the FLI float types :float, :double, :lisp-float, :lisp-single-float and so on, then the value of language should be :ansi-c
.
module is processed as for define-foreign-function.
The following example illustrates how to use the FLI to define a foreign variable, given the following C variable in a DLL:
int num;
The first example defines a Lisp variable, num1
, to interface with the C variable num
.
(fli:define-foreign-variable (num1 "num") :type :int)
The following commands return the value of num
, and increase its value by 1:
(num1)
(incf (num1))
In the next example, the Lisp variable num2
interfaces with num
in a read-only manner.
(fli:define-foreign-variable (num2 "num") :type :int :accessor :READ-ONLY)
In this case, the next command still returns the value of num
, but the second command raises an error, because num2
is read-only.
(num2)
(incf (num2))
The final example defines a Lisp variable, num3
, which accesses num
through pointers.
(fli:define-foreign-variable (num3 "num") :type :int :accessor :address-of)
As a result, the next command returns a pointer to num
, and to obtain the actual value stored by num
, num3
needs to be dereferenced.
(num3)
(fli:dereference (num3))
Foreign Language Interface User Guide and Reference Manual - 01 Dec 2021 19:34:58