|
Allegro CL version 11.0 |
function, foreign-functions package
Arguments: n
Convert the integer n, which should be a pointer to an object in memory, to an aligned pointer. See aligned-to-address and Aligned Pointers and the :aligned type in ftype.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: n
Convert the aligned pointer n (which is a fixnum) to the address of the object into memory to which it points. See address-to-aligned and tml#aligned-pointers-1) in ftype.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: type &optional allocation size
This function allocates an object of the given type in the heap area described by the allocation argument. If the size argument is given, then it is the minimum size (in bytes) of the data portion of the object that will be allocated. The function sizeof-fobject, which returns the size of an object of the given foreign type, might be useful in determining possible values for size.
The valid allocation argument values are as follows (default is :foreign). type should be a type defined with def-foreign-type.
:foreign - The object is allocated in the lisp heap using a lisp data type unique to Allegro called the (array excl::foreign). This kind of array has one lisp slot at the beginning, with all subsequent slots holding raw integer data. The foreign types facility uses the first, lisp-valued, slot to hold a pointer to a description of the type of data held in this object. Because these objects are stored in the Lisp heap, it doesn't make sense to ask for the address of a slot of one of these objects, as it may have moved by the time you get your answer.
:foreign-static-gc - These objects look just like :foreign allocated objects. The difference is that they are allocated in static space (i.e. space allocated with aclmalloc
). Unlike other objects allocated in static space, these objects are automatically gc'ed (the C aclfree
function is called on them) when the last pointer to them in the Lisp heap disappears. The advantage of this allocation type over :foreign
is that the object doesn't move. This makes it very useful when the object must be passed to a C foreign-function that releases the heap (e.g. most functions in the Windows package).
:lisp - A lisp array of type (unsigned-byte 8) of sufficient size to hold the object is allocated in the lisp heap. The object does not record the foreign type of which it is an instance. This allocation type is useful if you've got a binary file you want to read and take apart, and the format of the file is described by a C struct definition. In that case you can allocate an object of type :lisp
and then call read-sequence to read the data from the binary file into the foreign object. Note, however, that read-sequence will also work for :foreign
allocated objects.
There is one tricky case for 32-bit Lisps (it is not an issue on 64-bit Lisps): if the foreign structure requires 8 byte alignment (e.g. it begins with a double float) then the first four bytes of the lisp array allocated will not be used by fslot-value-typed. If you read-sequence into such an array, then your data will be displaced 4 bytes from where fslot-value-typed thinks it is.
:lisp-short - A lisp short-array of type (unsigned-byte 8) of sufficient size to hold the object is allocated in the lisp heap. The object does not record the foreign type of which it is an instance. This type is the same as the :lisp
type described just above, except that the data is held in a short-array. (short-arrays are a new data type corresponding to the older array type in Allegro CL. See Arrays and short arrays section in implementation.html.) Except for using a short-array, this type is the same as :lisp
.
:c - The object is allocated in static space (via aclmalloc) which is like C's malloc except that the data is preserved through a call to dumplisp) and a pointer to the space is returned. Thus the object is represented by an integer value. The object is not automatically freed. You must do the freeing with free-fobject
:aligned
- This is just like :c
except that it returns an aligned pointer. Objects allocated in :aligned
mode should be freed with free-fobject-aligned.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: type &optional size
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to an allocate-fobject call as quickly as possible. (Use the allocation argument of allocate-fobject to specify where the allocation should occur. Specify :c
for allocation to get behavior equivalent to this macro.)
This function allocates an object of the given type in the C heap. If the size argument is given, then it is the minimum size (in bytes) of the data portion of the object that will be allocated. The object will not be moved by the garbage collector. The object will not be automatically reclaimed. To return the space to the C heap, call free-fobject-c. This object is represented in lisp by an integer (which points to the beginning of the object in memory).
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: type &optional size
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to an allocate-fobject call as quickly as possible. (Use the allocation argument of allocate-fobject to specify where the allocation should occur. Specify :foreign-static-gc
for allocation to get behavior equivalent to this macro.)
This function allocates some data in the C heap. The object allocated will be automatically garbage collected when it's no longer in use.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: id &rest def
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: id val
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: id
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: id &rest def &key all-names unconverted-entry-name return-type c-arg-names arguments &allow-other-keys
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: type
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: id &rest def
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
Macro, foreign-functions package
Arguments: id &rest def
This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.
function, foreign-functions package
Arguments: ftype
If ftype is or names a foreign type, return the symbol or list that describes that type, otherwise return nil
.
If ftype is a symbol defined using def-foreign-type, then the definition form is returned. If ftype is one of the primitive foreign type symbols or is a list in the form valid for def-foreign-type, then ftype itself is returned. If ftype is a symbol that has been given a foreign type definition through def-foreign-type, then the foreign definition is returned. Using canonical-ftype allows a quick determination of whether a symbol names a simple type or a structured type.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: address
This function is obsolete and maintained in the :ffcompat
compatibility module, which is loaded automatically when this function is called. It has been replaced with char*-strlen. Using char*-strlen means fewer modules need be present in an image using this functionality.
Returns the length of the C string located at address. This function is useful when calling char*-to-string with the optional string argument specified. Since the length of the Lisp string provided as the receptacle of the C string is not modified, you may not know how much was copied from the C string without the aid of this function.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: address
ff:char*-to-euc is obsolete. native-to-octets should be used instead. Using native-to-octets means fewer modules need be present in an image using this functionality. ff:char*-to-euc is defined in the :ffcompat
module which is not present in an image by default.
This function converts a C-style (char ) string (which must be null-terminated) to a Lisp (unsigned-byte 8 ()) array. The resulting array consists of the characters from the source string in EUC code.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: address &optional string make-string-p
This function is obsolete. It has been replaced by native-to-string. A call to char*-to-string is converted to
(excl:native-to-string *address*
:string *string*
:make-string? *make-string-p*:default) :external-format
Users are encouraged to use native-to-string instead of char*-to-string for new code. See also string-to-native and with-native-string. Using native-to-string means fewer modules need be present in an image using this functionality.
The remainder of this description is the old documentation for char*-to-string. The function is defined in the :ffcompat
module which is not present in an image by default.
This function returns a Lisp string. address should be a integer returned by a foreign function. char*-to-string converts a C string to a Lisp string by copying the elements of the C character array into a newly allocated Lisp string. A C string is really just an array of characters ending with a null character.
char*-to-string takes a second, optional, string argument which if given should be a string large enough to hold the contents of the char*. If the string is long enough, then it is used to store the char*. If the given string isn't long enough, an error will be signaled, unless a third argument is given and is true, in which case a long enough string will be created (but string will not be used).
If the second argument, a string, is given then the following should be noted: The string must be a simple string. If the string is long enough then it will be filled with the characters pointed to by the char*. The null terminating character will not be stored in the string. After char*-to-string is run, the size of the lisp string will be unchanged. In order to determine the length of the string copied the program can either call char*-strlen on the char* value, or it can fill the string with #\null's before calling char*-to-string.
Note to users of International Allegro Common Lisp (see iacl.html): This function will only copy single byte character from foreign space. However the characters will be stored correctly in double-byte Lisp character strings. The function native-to-string should be used to copy double byte characters from foreign space. The function is described in iacl.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: body &optional keys errorp
This function takes a foreign type specification (in the body argument) and converts it to an internal representation. It is not normally necessary to call this function since most foreign type functions pre-internalize the foreign type specifications which they accept. errorp defaults to t
. If nil
, nil
is returned but no error is signaled if body specified an invalid type. keys is a list of attributes and defaults to nil
. See def-foreign-type where acceptable attributes are listed.
user(10): (setq ftype (compile-foreign-type '(:struct (x :int) (y :int))))
nil
#S(foreign-functions::iforeign-type :attributes
:sftype
#S(foreign-functions::sized-ftype-struct
:kind :struct8
:width 0
:offset 0
:pad 4
:align
:canon (:struct # #) :slots (# #)))
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &key language
The name argument is coerced to a string and the case mode is massaged, and prefixes/suffixes are added based on the language (which defaults to :c
) to create an appropriate name to match the equivalent foreign entry point name. For example, 'sbrk
might become "sbrk" on some systems, or "sbrk" on others. Or a call to a fortran 'subx
might be translated to "subx". The language argument can be :c
or :fortran
.
Note: This is the default conversion function for def-foreign-call, and is applied at foreign call definition time, either at the top level or as a source or fasl file is being loaded. Other functions may be used instead; in particular we supply a function called excl::ics-mode-convert, which is used in Windows 98/Me/2000 and NT/xp API interface definitions to select between the 8-bit ascii and wide versions of the library function (signified by appending "A" or "W", respectively).
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &key language
This function is obsolete and its use is discouraged except in code being ported from Allegro CL 4.3. It is replaced by convert-foreign-name.
This function takes the string arguments and returns a string of the correct form for the system. The keyword language is either :c
or :fortran
, with the default being :c
.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name &rest slots
This macro is obsolete and kept for backward compatibility only. Please use def-foreign-type.
This macro returns name if name is a symbol or (car name) if name is a list but it is used for its side effects. The side effects are (1) defining a C type which can be created by Lisp; and (2) defining constructor and accessor functions which can be used, respectively, to create instances of the C type and access the values of the C type. You can specify that instances be located in Lisp space (the default in most cases), which means the instance may be moved by the garbage collector, or in foreign (also called C or malloc) space. Objects in C space are never moved. We will return to the difference between Lisp and foreign space below.
You can also control whether accessor functions and/or constructor functions are created. Note that if you want to define a type whose only use is as a part of another type, you should call def-c-typedef instead of def-c-type.
The argument name must be a symbol or a list whose first element is a symbol. The symbol becomes a name for the C data type. If the value of name is a list, the elements after the symbol (the first element) must be the keywords :in-foreign-space, :no-defuns, or :no-constructor
. Any one or two or all three may be included in the list.
If you specify :in-foreign-space in the list, any instance of the type created with either the constructor function (described below) or make-cstruct will be located in foreign space and never moved by the garbage collector. Such objects can be repeatedly accessed by either C or Lisp since the addresses known to C will never become invalid. These types can be used as a communication channel between C and Lisp. If that keyword is not used, instances will be created in Lisp space. If an object is stored in Lisp space, great care must be used when accessing it from C since whenever Lisp code is run, the object may be moved. Typically, such items are only accessed by C once and are thereafter used only by Lisp or are disposed of.
If you specify :no-defuns in the list, no accessor functions will be defined. You typically do this when your code is well debugged and such functions are not necessary to run your application, thus saving space. If you do not specify :no-defuns, accessor functions will be defined. The accessor functions are named by appending -[slot-name]
to the symbol. If there are no slots (see below), the symbol itself denotes the accessor function. Accessor functions always take either the object or its address as an argument and may take further arguments if more are necessary.
If you specify :no-constructor, no constructor function will be created. Then, you will only be able to create new objects of the type with make-cstruct taking the (quoted) symbol as an argument. Note that an object of a type defined with def-c-typedef cannot be created even with make-cstruct. Calling the constructor function (if one is created, it will be named make- followed by the symbol) or make-cstruct will cause the new object itself to be returned if the object is in Lisp space and the address of the new object (suitable to be passed to C) if the object is in foreign space.
You must also specify one or more data-types. More than one are allowed for backwards compatibility with defcstruct. We recommend using one data-type only and will not discuss using more than one. The data-type may be one of the following (in general, datatypes are C datatypes prefixed with a ':` to make them keywords):
:char | :signed-char | :byte
:unsigned-char | :unsigned-byte
:int | :long | :signed | :signed-int | :signed-long
:unsigned-int | :unsigned-long | :unsigned
:short | :signed-short
:unsigned-short
:float | :single-float | :short-float
:double | :double-float | :long-float
:bit integer
*data-type
integer data-type
:union (slot-name data-type)+
:struct (slot-name data-type)+
You specify exactly the keyword named in the first eight cases. The types specified on a single line (and separated by vertical bars) are equivalent types: thus you achieve the same thing by specifying :char or :byte, both are equivalent. If you specify :bit (for a bit array), you follow it with an integer which indicates the number of elements in the array. You may specify a * followed by a data-type (that is anything in the list) to get a pointer to that object. You may specify an integer followed by a data-type to get an array of objects of that type. Note that * and integer are recursively defined so as many *s and integer
s as you want may be used.
You may specify a structure or a union with :struct or :union, followed by lists (as many as you wish) of the form
(slot-name data-type)
Here slot-name is a symbol and data-type is a data-type defined above.
Finally, the value of data-type may be any symbol specifying a data-type already defined with def-c-type or def-c-typedef.
As we said above, objects of this type are created with constructor functions or with make-cstruct. In either case, the value returned is either the object itself (for objects in Lisp space) or the address of the object (for objects in foreign space). Note that the address will be understood by the accessor functions and can be passed to C, etc., but is just an integer as far as most Lisp functions are concerned.
Values stored in the various slots can be set with setf and the accessor function. Lisp values are converted to the appropriate C value when they are stored in most cases (or an error is signaled if that is not possible). When accessed, the C values are converted to the appropriate Lisp value, again in most cases and when possible. Note that there are special accessors when you use already defined structures to build new structures in foreign space.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name &rest slots
This macro is obsolete and kept for backward compatibility only. Please use def-foreign-type.
This macro returns name if name is a symbol or (car name) if name is a list but this macro is used for its side effects. The side effect is to define a C type to Lisp. (The list of allowable types is the same as given in the definition of def-c-type. It includes structures and unions as well as ordinary types.) However, unlike the related macro def-c-type, no accessor functions and no constructor functions are defined. You cannot even use make-cstruct to create an object of the defined type. The purpose of def-c-typedef is to provide building blocks which will be used by def-c-type (which does create accessors and a constructor as side effects) without paying the overhead of defining the additional functions. def-c-typedef takes the same arguments as def-c-type. (If the name argument is a list, only the first element, which must be a symbol, is used. A list is accepted for compatibility with def-c-type.)
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name-and-options arglist &key call-direct callback convention returning libname lisp-return-will-not-move method-index release-heap release-heap-ignorable arg-checking optimize-for-space strings-convert error-value pass-structs-by-value allow-gc release-heap-implies-allow-gc documentation
This macro creates the specification which allows Lisp to correctly call non-Lisp code. Like other defining forms, its macroexpansion clearly shows what will occur and at what eval-when times. The execution of the expanded form always returns the Lisp name being defined. The definition that is installed is a Lisp function that serves as a wrapper and initiates the foreign call.
Macroexpansion of a def-foreign-call form provides useful information about how the call is interpreted. See below.
The following table shows the arguments. The first two entries are the required arguments and the remainder are keyword arguments.
Argument | Value and Details | Notes |
name-and-options | A required argument.
Symbol or a list of a symbol and an external-name specification, which can either be: (1) a symbol naming a function of one argument that returns a string to be used as the foreign name or (2) a string which will be used as the foreign name. |
The symbol represents the lisp-name for which the foreign-call definition will be installed. The external name specification can be either a string specifying a literal external name, or it can be a symbol, which represents the name of a conversion function. That conversion function must take one required argument and at least the language keyword argument, and must be defined at the time the macro expansion is executed. At that time this conversion function will be called and will receive the lisp-name specified, as well as the arguments ':language lang' where lang is the value of the *convention* keyword argument to def-foreign-call. |
arglist | A required argument. A possibly
empty list of
argument specifications. |
nil implies
much the same as it does in C, that arguments are
not checked for type or number.
(:void) means 0 arguments are explicitly required (also as in C). Note that string-conversion is done automatically when
arglist is Otherwise a list of argument specifications. See Note 1: Argument Specifications after the table. See A note on foreign addresses
in foreign-functions.html
for a discussion of
foreign addresses and what is expected
when |
returning |
Keyword argument.
Default: the foreign type The value can also be: A foreign type (defined by def-foreign-type A list of a foreign type and a Lisp type. Example:
A list of a foreign type, a Lisp type, and a symbol naming a
user-defined conversion function. Example:
|
This argument specifies how the value returned
from the foreign function will be interpreted. If both foreign and
Lisp types are chosen, they will be checked for consistency and a
warning might be given. A common idiom is to use
to specify that the foreign value returned is to be simply shifted into a fixnum value, with no consing and simple truncation of the top two bits on overflow. If |
libname | If specified, the value must be a string.
It indicates
that the entry-point that is recorded for this call is not
dynamically snapped to any shared-library that is newly loaded,
but instead only updates to a library whose namestring or name
component contains the libname string.
Normally, if liba.so and libb.so both contain the entry point "foo",
then But for entry points that need to be only associated with a specific library, it is dangerous to not guard against the possibility that someone has defined a foreign function with the same name, but with a different interface (which could prove to be fatal). A (undocumented) technique that we have used in the past is to make the entry point "static" and that works as long as it is done within the same Lisp, but if dumplisp is used to create a new image and that image is started up, perhaps at a later time or in a different machine, the address of the entry point may have changed, and calling the foreign function would then result in an exception that could kill the lisp.
As a real example, on Macs the SSL (secure socket layer) has a library
named libcrypto.dylib, which contains among others the entry-point
named "EVP_MD_size". However, the CoreGraphics library contains its
own version of EVP_MD_size, not necessarily with the same interface as
the version in libcrypto, which we load from our use of openSSL.
So when one loads CoreGraphics.dylib, how does one stop the entry
struct from now pointing to the entry in CoreGraphics? The new
(ff:def-foreign-call (evp-md-size "EVP_MD_size") (...) ... :libname "libcrypto" ...) This definition will ensure that the entry-point structure associated with evp-md-size will only be updated if a library with "libcrypto" somewhere in its namestring or the name component of its pathname is loaded. Any other library name will result in the entry struct being left alone, even if that library has defined an entry named EVP_MD_size.
Note that this mechanism is simplisitic and does not guard against all
redefinitions, specifically if there are libraries loaded that have
similar names. Care must be taken to choose the
Note that on the FreeBSD platform, there is no way to
determine accurately where the
symbol is loaded. Thus, on a freebsd system,
the |
|
lisp-return-will-not-move | Keyword
argument. Default nil . If specified true, no
warning will be signaled if the value
of returning
is :lisp . See Note
9 on the :lisp return type below.
|
|
convention | Keyword argument. Default :c
Other possibilities listed in Note 2: Possible Values for Convention after the table. |
This argument allows the specialization of calling conventions due to language or operating-system distinctions. The default convention is :c, and is adequate for most situations. (Note that on Windows the c/stdcall convention distinction is required for callbacks using defun-foreign-callable, but is not required in def-foreign-call). |
arg-checking | t or nil (default is t unless
arglist is nil ) |
If true, this argument causes
the Lisp wrapper function to first check the
Lisp types against the Lisp argument type specifications.
When nil , no
argument checking is done (although the number of arguments
might still be checked). If
true, the lisp-types specified or
implied in the argument specification
(provided with the arglist argument)
is used to check the actual arguments to the
wrapper; if a mismatch occurs, error is called.
An argument specification |
call-direct | t or nil
(default is nil ) |
The argument causes no changes to the
Lisp wrapper itself, but, when
specified true, allows for other Lisp functions to call
the foreign function directly when
compiled after the def-foreign-call
form is in effect. In order for the
compilation of a direct-call to be successful, the
argument and return types must imply
simple type conversions which the compiler can handle.
That list of direct-callable
conversions on a platform is constantly changing, but can be
examined by calling the
function
list-call-direct-possibilities.
If
for any reason a call to the foreign function cannot be
compiled into a direct-call, a
warning is issued and a call to the wrapper is generated.
When error-value is non- |
method-index
|
nil (the default)
or an index into C++ table, as described at
right. |
This argument allows for calling of
C++ style member-methods. The value,
if specified, must be an integer index into the virtual
table of the C++ class. Symbolic
index specifications are not directly supported.
See Note 6: More on the
:method-index argument for information on a
non- |
callback | t (the default and only allowed value) | The callback keyword is no longer operative, and use of it will cause a warning. |
release-heap | Only used on platforms that use the :os-threads model for multiprocessing. See Note 3: the release-heap keyword argument below the table. | The
release-heap keyword allows the foreign function
to operate in native-OS threads (so :os-threads is on the
*features* list), without
causing conflicting demands on the Lisp heap. The values for this
keyword are discussed in Note 3: the
release-heap keyword argument below the table. Note: the
specification of :release-heap on any non-os-threads implementation to
any value other than :never will generate a
warning, unless the user also specifies :release-heap-ignorable as a
non-nil value.
|
release-heap-ignorable | t or nil (default is nil ) |
This
argument, when t , tells the system to
ignore the release-heap keyword
argument, regardless of its value, on non-os-threads
implementations. The value on non-os-threads implementations
should be :never .
If the value of this argument
is nil , a warning will be generated if
the value of the release-heap is anything
other than :never . (The reason is such a value
is meaningless and the system wants to be sure that the programmer
understands that a meaningless value has been specified. Assuming
that the heap can be released on non-os-threads (it cannot be
released) may affect behavior or performance.) This argument is
provided to allow the same
def-foreign-call forms to be
used on both os-threads and non-os-threads platforms without
warnings being signaled and without conditionalizing the value
of the release-heap argument.
|
allow-gc | :never , :always , or
:when-ok (default
is :never ) |
This argument can have the same values as
release-heap, and they roughly mean the same
thing, except here applying to the garbage-collector is allowed to run
either never (with :never), when interrupts are enabled (with
:when-ok) or always (with :always). See Note 3: the release-heap keyword
argument below the table. This argument is only used in an SMP Lisp.
It is planned to add as an allowable value :match-release-heap and eliminate the :release-heap-implies-allow-gc argument. |
release-heap-implies-allow-gc | t or nil (default is nil ) |
If in an SMP Lisp the release-heap argument is
given a value other than :never , then a warning is
issued. This is because :release-heap is a confusing concept in an
SMP world, and it is necessary to require users porting to SMP Lisps
to explicitly state what is desired for SMP, regardless of the options
used for os-threads or virtual-threads (where Lisp processes are
managed within Lisp). So the user can elect to use conditional
reading using #+os-threads, #+smp, etc., or these conditionalizations
can be avoided with release-heap-implies-allow-gc
which says "I understand that in an SMP Lisp we are really allowing
the gc, but I want to use the release-heap argument to specify this".
It is the intention to remove this argumement and allow an additional value for allow-gc to replace it. |
optimize-for-space | t or nil (default is nil ) |
The optimize-for-space keyword provides for minimal space requirement for foreign-call wrappers. This option is best used in conjunction with the call-direct option. If true, optimize-for-space will ensure that the wrapper definition takes up very little room, usually as a closure. This usually comes at a cost of speed, and so only makes sense when call-direct is used to compile all actual calls to the foreign function directly, so that the Lisp wrapper is not called normally at all. |
strings-convert | t or
nil
(default is t ) |
This argument assists in having the
foreign-function
interface handle Allegro CL's 16-bit strings automatically.
When the strings-convert is true, then
when any of the specified
arguments at def-foreign-call time are declared directly or indirectly
as (* :char) ,
def-foreign-call augments the
function wrapping the low-level foreign function call so that for each
(* :char) declared argument, a check is made at
runtime to see if that declaration's corresponding value is a string.
If it is, then that value is converted at runtime to native-string
format using a dynamic-extent array, and this new array is passed in
place of the original string argument to low-level foreign function
call. See Foreign-Functions in
iacl.html for full details and examples.
If arglist is |
error-value | nil ,
:errno , :os-specific ,
(default is nil ) |
nil causes normal operation of the foreign call
and a return of the one value that the foreign call itself
returns.
call-direct is
ineffective if error-value is
non- See Note 5: More on the error-value argument after the table for more information. |
pass-structs-by-value | nil
or t , default is nil
|
nil causes an argument structure not
specified with a * to be passed by reference anyway. So an argument
specification (point Point)
with pass-structs-by-value nil will be passed by
reference, as will (point (* Point)) ,
while (point Point)
with pass-structs-by-value t will be passed by
reference. Structs can be passed by value or reference as arguments
and returned by value or reference as well. See also the variable
\*pass-structs-by-value\*,
which is bound whenever
def-foreign-call is invoked, either to
the keyword value, or to its current value.
If not specified, a warning is issued. See Passing structures by value in foreign-functions.html for details. |
documentation | nil
or a string, default is nil
|
Supplies a documentation string for the foreign function. The string
can be accessed with (documentation name
'function) . You can set the documentation after definition
with (setf documentation]). If
\*load-documentation\*
is nil , documentation string is effectively
ignored.
|
Argument specifications are available with a rich set of syntax and defaults which allow for a C "feel" while still retaining the Lisp semantics and power.
The elements of an argument list can be:
(:int (integer \* \*))
but starting with 11.0 the implied equivalent corresponds more correctly to the C type by becoming (:int (integer -2147483648 2147483647))
. If the foreign call is being defined with :arg-checking
true, this can lead to calls to error which would not happen in versions prior to 11.0.(name type)
, where name
is a symbol and type
is either a built-in foreign type, or a type defined by def-foreign-type, or one of the keywords :lisp
, :foreign-address
, or :aligned
. We discuss the keywords below.(name type lisp-type)
, where name
and type
are as above, and lisp-type
can be any valid Lisp type. It specifies the type of the value passed. If the lisp-type
is not consistent with the foreign type
, a warning may be signaled.(name type lisp-type user-conversion-function)
, where name
, type
, and lisp-type
are as above, and user-conversion-function
is a symbol naming a function, described in the section The user-conversion function in a complex-type-spec in foreign-functions.html.If an argument is specified as an elipsis (either a string with 3 dots, i.e. "...", or a symbol in any package, e.g. user::|...|
) then arguments before it will be interpreted as being typed, as if the elipsis had not been there, but arguments passed in beyond the elipsis specification will be treated as if the def-foreign-call had been made with no prototyping; i.e. the number and type of the arguments from the elipsis and beyond are ignored.
The allowable keywords for the foreign type (second list element) are:
:int
: the default, the argument will be converted to a C integer. In the two element list case, this will result in a Lisp type normalized to (integer -2147483648 2147483647)
.:lisp
: the argument will be passed unchanged. analogous to the returning type :lisp
.:aligned
: like :lisp
(in that the argument is passed through unchanged) but the argument value must be a fixnum. If arguments are checked, a value other than a fixnum will be rejected. See Aligned Pointers and the :aligned type in ftype.html for more information.:foreign-address
: the argument value should be an integer which will be interpreted as a foreign address.Here is an example:
fixnum) (c :lisp)) (a (b :int
A foreign type specification that includes a reference spec such as (& :int)
will be interpreted as a pass-by-reference argument.
For boolean values, specify the argument (argname :int boolean)
. Then any non-nil
Lisp value (including 0) will be converted into a C value of 1, and nil
will be converted into a C value of 0. For returned values, a C value of 0 is converted into nil
and a non-zero C value is converted into t
.
The special Lisp type specification :no-proto
is provided for use with a :float
foreign type (but its use is deprecated); it is equivalent to the :single-float-no-proto
foreign type (not listed above because it is deprecated). The preferred specification is (name :double single-float)
.
Specifying (* :float) or (* :double) as the type of an argument is not recommended. The function will expect a foreign address (not a Lisp address) and it will not pass the address of a Lisp float if a Lisp float is given as a value.
See A note on foreign addresses in foreign-functions.html for a discussion of foreign addresses and what is expected when :foreign-address
is specified.
Other than :c
, (the default and suitable for most purposes), the :fortran
convention is defined. This convention generally causes a conversion of most atomic arguments to pass-by-reference.
:fastcall
is a special convention used by some Windows operating systems to speed up some calls, by passing two arguments in registers. However, it does not work with Allegro CL. In Allegro CL on X86 architectures, the first two arguments are usually passed in registers anyway in Lisp, but they are different registers than used in fastcall. Also, since the calling sequence itself overshadows the speed that would be gained by saving a couple of push instructions, the foreign call to a fastcall function would not in fact be very fast at all.
The native-threads implementation of Allegro CL changes some basic assumptions of the foreign functions user interface. There is always exactly one native thread per Lisp Process, but there is not necessarily a Lisp process for every thread. Threads are free to run whenever they want; however, only one thread at a time can access the Lisp heap (for read or write); a thread cannot access the Lisp heap unless it has "acquired" the heap, which is only possible after another thread has "released" the heap.
See Releasing the heap when calling foreign functions in foreign-functions.html for more information on this point.
def-foreign-call allows for the specification of whether to release the heap or not during a call. The possibilities for the release-heap keyword argument are:
:never
- This is the default and is compatible to the original defforeign interface; the caller necessarily has the lisp heap, this call will not release it. Note that if the foreign code being called spawns any new threads, or if it allows another thread to run, and the other thread attempts to call back into lisp, it will have to wait for the lisp heap. The danger is that the original thread may be waiting for results from its partner thread, but it has not yet given up the heap (this constitutes a deadlock situation). If this situation holds (foreign code does spawn new thread which call back into Lisp), :when-ok
is the appropriate value for the release-heap argument.
:always
- The foreign call always gives up the heap before making the transition into non-lisp execution. If the form is being called within the dynamic context of a without-interrupts form, an error is signaled.
:when-ok
- The current dynamic context is examined, and if without-interrupts is in effect, the heap is not released; otherwise the heap is released.
There is a big difference in dealing with other-thread and garbage collection (gc) action intermingled with foreign calls in all of virtual-threads (processes are managed by Lisp), os-threads (processes are managed by the OS, but only one hardware processor is used for Lisp code), and SMP (multiple hardware processors can be used for Lisp and foreign code) Lisps. All three are different. This makes designing functionality which will run correctly on all three complicated.
The release-heap argument was added for os-threads, and has options :never, :always, and :when-ok. These are still the options. They pertain to whether the thread calling a foreign-function wants to allow another thread to access the Lisp heap during the call (note that amonst other things, this could lead to a garbage-collection).
The virtual-threads Lisps are simpler. Because they are more constrained, :release-heap :never is the only option that makes sense, since there is no concept of releasing the heap by a thread separate from pausing the thread.
If the user is coding for both virtual and os-threads, he can code for os-threads, and then add the :release-heap-ignorable t option to allow virtual-threads calls to compile without warning (and with the implied descriptive value of :never for the :release-heap option).
SMP Lisps are more complicated As with virtual threads, there is again no concept of heap ownership, in this case not because the heap is automatically assigned to the running thread, but because there are no longer any heap management constraints except one (explained later) which means that any thread can access the heap at any time. So the concept of releasing the heap makes even less sense in an SMP Lisp than it does in a virtual-threads Lisp.
In a pure SMP Lisp, there would be no restrictions at all on foreign calls. But, as mentioned above, although the heap itself is no longer a one-at-a-time resource needing gating, the garbage-collector, which is a stop-the-world collector still, must have complete and exclusive access to the heap when it runs, and so threads must specify whether to allow the gc to run.
def-foreign-call has two new keyword arguments: allow-gc and release-heap-implies-allow-gc to deals with these issues.
allow-gc,defaults to :never, to keep it in line with the release-heap argument. It can have the same values as release-heap, and they roughly mean the same thing (with the difference being that the garbage-collector is allowed to run either never (with :never), when interrupts are enabled (with :when-ok) or always (with :always). Note that as with os-threads, in an SMP Lisp, :allow-gc :never
does not lock out the gc if the foreign code performs a callback to Lisp. So appropriae measures must still be taken, if a callback is possible, to reacquire Lisp objects after a possible gc, because they may have moved.
(ff:def-foreign-call foo ())
has no arguments specified, meaning that any number of arguments of any type will be passed. If any of these arguments are strings, it may be that string conversion should be performed.
String conversion is done by default. The above def-foreign-call form will generate a warning message (to indicate that string arguments will be converted). To suppress the warning but still convert the strings, specify the value t
for the strings-convert keyword argument. To suppress the warning and to suppress all automatic strings conversion, specify the value nil
for the strings-convert keyword argument.
Getting an error value from a foreign call is somewhat complicated, so users should not casually use this feature, but instead consider whether the information is necessary and be aware of various ways in which the information may be incorrect.
First note the following:
The cost of obtaining the error value and returning it as the second value is not insignificant, so the value should only be obtained (by specifying a non-nil
value for the error-value argument) if there is reason to believe it may be needed.
The only way to get the correct value is to specify the correct non-nil
value for for the error-value argument. Foreign function call are complicated and typically additional functionality is wrapped around the actual function call by the system (that is, by Allegro CL). This additional functionality may affect the value of the errno system variable in the current system thread or the value returned by GetLastError() so simply looking at errno or calling GetLastError() after the forreign call has returned will not work: the value seen can be different from the correct value. When error-value has an appropriate non-nil
value (appropriate values are discussed below), code is added by the system to get and store the value of errno or the return value of GetLastError() immediately after the actual foreign function returns (and before the additional wrapper code is run). Using error-value is the only way to get the correct value, and even that may not always work, as the next bullet discusses.
The returned as the error value assumes the foreign function being called behaves correctly with regard to errors. Thus, the value of errno has to be set to 0 at the beginning of the call or the error value seen by GetLastError() has to be cleared. Then the value seen when the call returns will be correct. If this is not done, then the value seen need not be correct. So, for example, if the foreign call does nothing to set errno, and its value happens to be 2 when the call is made, and the function runs without error so errno is not affected by any error handler, then the return error value will be 2 even though it should be zero. Note that this has nothing to do with Allegro CL and the code it generates. Allegro CL is returning what it promises: the value of errno or that retruned by GetLastError() immediately after the foreign function returns. It is just that value in such a case is bogus. The Allegro CL shared library does have a function clear_errno_value(). While this can be called by the actual foreign function, if you have such a function where you cannot modify the source, you could call this function, either in a wrapper around the foreign function of interest or even in a separate foreign call prior to the call of interest and, while not guaranteed for reasons just given, will make the second return value more likely to be correct.
The two acceptable non-nil
values for error-value are :errno
and :os-specific
.
The two non-nil
values have the same effect: the value of errno is stored immediately after the actual foreign function returns (and before additional wrapper code is run), and then returned as the second return value of the foreign call.
The values have different effects.
If you specify the value :os-specific
, then GetLastError() is called immediately after the actual foreign function returns (and before additional wrapper code is run), and then returned as the second return value of the foreign call. This is the standard Windows procedure, and works for all standard Windows routines, for example LoadLibrary() (see the description of that function in the MSDN where it says that you get error information by calling GetLastError()).
If you specify the value :errno
, then the value of errno is stored immediately after the actual foreign function returns (and before additional wrapper code is run), and then returned as the second return value of the foreign call. This is not standard Windows procedure, but is how some routines work, particularly those which are provided in UNIX-like libraries. This is often how Windows versions of open() works, for example, (open() is not a standard Windows function).
On Windows, you must specify the appropriate way to get the error value for the routine you are calling. Specifying :errno
will give a wrong value for LoadLibrary(). Specifying :os-specific
will give a wrong value for (many, perhaps all implementations of) open().
This argument is supported on Windows only. If a non-nil
value is specified for the method-index keyword argument, then the value must be a vector whose first value is the integer index into the virtual table of the C++ class. And then, when the foreign function is called, the first argument of the call must be the vector whose first element is an integer which is a pointer to the table of method addresses. The arguments specified to def-foreign-call follow that first argument. Note that the function name specified in the def-foreign-call form is used only for the Lisp function name, and does not refer to any function in a shared library. Instead, the function's address (as a table address and an index into the table) is passed when the function is called.
def-foreign-call is defined to default its :returning keyword argument (specifying the expected type of value returned by the foreign call) to :int
. :int
corresponds to C's int type. However, if the foreign function does not actually return an int, subtle bugs could be introduced in programs, particularly if the C function returns a long, an unsigned long, or a pointer of some sort. In 32-bit Lisps, returning those values is not a problem (when :returning :int
is specified or defaulted to) because int is always 32 bits on every architecture we support. But on 64-bit Lisps, if a 64 bit value is returned, the upper 32 bits are lost. If the value was not correctly sign-extended by the foreign code, a negative value in the foreign code could be seen by Lisp as a large positive value. Also, the :long
or :unsigned-long
type is an inadequate specfication because on Windows long types are always 32 bits. So on either 32 or 64 bit lisps, for portability, use :returning :unsigned-nat
when the return value is some kind of pointer. (See The :nat and :unsigned-nat types in implementation.html for a description of the :nat
and :unsigned-nat
types.) When the returned value is an integer value, be sure to use the correct type and be sure that the foreign code actually produces that type.
def-foreign-call can accept :returning :boolean
as a return type, and it will be automatically translated to a canonical form which is :returning (:int boolean)
. This works with some foreign languages (where 0 is considered false and anything else is considered true - it translates 0 into nil
on the lisp side and anything else to the value t
), but in some cases (C++, for instance) the boolean type is equivalent to signed-char type, and so it must be specified in the def-foreign-call as :returning (:char boolean)
.
The :lisp
return type means that the foreign code will return a Lisp object. For most Lisp objects (other than characters, fixnums, and a few others), this means returning a pointer to the object. If for whatever reason the object has been moved before the pointer is in a place where it can be seen by the garbage collector and properly forwarded, the pointer will be invalid and the result may be Lisp failure because of gc failure. For this reason, a warning is signaled when :lisp
is specified as a value for :returning
.
The warning can be avoided by specifying :aligned
instead of :lisp
as the :returning
value. Although aligned pointers could also represent objects that move during gc, it is much less likely so, because they tend to only be used when the objects they represent are static, like stack-based objects or allocated in aclmalloc space. Note associating the actual Lisp value with an :aligned
value is complicated. See Aligned Pointers and the :aligned type in ftype.html for more information.
If you are sure the item will not move (because it is located in statis space, for example), you can give t
as the value of the lisp-return-will-not-move
keyword argument. That supresses any warning about :returning :lisp
.
C compilers are inconsistent in the way they treat char
and unsigned char
types, if they even allow both definitions. But regardless of the types allowed, the C char
type is usually an unsigned integer and it can be used as a character or as a byte in C; C makes no distinction. When passing a char
to a language that does distinguish between a character and an integer, however, the distinction can only be known if the programmer's intent is made known by providing the distinction externally; it cannot be known if a char
coming into Lisp from C will be used as a character or as a small integer. So Allegro CL provides automatic conversions which will cover both cases: as of 10.1, Allegro CL converts the :char
primitive foreign-type to the lisp-type character
, and :unsigned-char
is converted to (unsigned-byte 8)
. Prior to 10.1 both types were converted to character
.
If it is desired to retain the effective argument declaration of (*name* :unsigned-char character)
then the Lisp type must be explicitly given, similar to this form.
(def-foreign-call add2 (x y))
The symbol add2 will have a function definition calling the foreign function probably named "add2" in C, whose first arg is named "x" and is an integer in Lisp and which is converted to an int for passing to C. If the integer is larger than can be held in a C int, it is truncated. As with the first arg, the second arg named "y" is an integer converted to a C int. The return value is interpreted as a C int type, and is converted to a Lisp integer (which may either be a fixnum or consed as a bignum).
We say the foreign function is "probably" named "add2" because since no specific name or conversion function is specified, the default system conversion function is used. It depends on the platform and platform-specific rules but typically downcases the symbol name.
(def-foreign-call t_double ((x :double)single-float)
(y :double fixnum))
(z :int :returning :double)
Call a function, probably named "t_double" in C (again "probably" because the actual name depends on platform-dependent defaults), whose first arg is a double-float both in Lisp and in C, and whose second arg is a single-float in Lisp but is converted to double float for passing into C (this is the calling convention used by some non ANSI C compilers and by others when the arguments are not prototyped), and the third argument is a fixnum Lisp passed as an integer to C. The function returns and boxes a double-float value to Lisp.
(def-foreign-call (t-float dash-to-underscore) ((x :double)
(y (:float :no-proto))fixnum)
(z :int * :char) string))
(w (or (and sun4 (not svr4)) sun3q) :float
:returning #-(or (and sun4 (not svr4)) sun3q) (:double single-float)
#+(
"t_float") ((x :double)
(def-foreign-call (t-float
(y (:float :no-proto))fixnum)
(z :int * :char) string))
(w (or (and sun4 (not svr4)) sun3q) :float
:returning #-(or (and sun4 (not svr4)) sun3q) (:double single-float) #+(
These two examples do the same thing: call a function, named "t_float" in C (assuming in the first case proper conversion by dash-to-underscore, which must already be defined and should downcase the symbol name and replace dashes with underscores), whose first arg is a double-float both in Lisp and in C. Like the previous example, the second arg is a float in Lisp, and is converted to double float for passing into C. The third arg named "z" is a fixnum passed as an int, and "w" is a (null-terminated) Lisp string, whose first-character-address is passed to C (beware, the string may move if a gc is allowed). Depending on the architecture, the C function will return either a double (from older C compilers) or a float, each interpreted and boxed as a Lisp single-float value.
We give both examples to show how a lisp name (the symbol t-float
) is converted to a foreign name ("t_float"). You can either specify a function that takes a symbol as an argument and returns the correct string (so (dash-to-underscore 't-float)
returns "t_float"
) or you can simply specify the correct string. Note again that dash-to-underscore must be already defined when the def-foreign-call form is evaluated.
def-foreign-call has enhanced the macroexpansion to give useful information for users. Here is an example:
11): (pprint
cl-user(macroexpand '(ff:def-foreign-call foo (x (y (* :char))))))
(
Warning: A runtime with-native-string call is being generated for argument `y'the foreign-function `foo'. The with-native-string macro can be
to string conversions around the foreign calls. This
used for explicit warning is suppressed when :strings-convert is specified in the
def-foreign-call.
progn (eval-when (:compile-toplevel)
(
(excl::check-lock-definitions-compile-time 'foo 'functionfboundp 'foo))
'foreign-functions:def-foreign-call (
(excl::compiler-note-fboundp 'foo))eval-when (compile load eval)
(remprop 'foo 'system::direct-ff-call))
(setf (fdefinition 'foo)
(let ((excl::f
(
(named-annotated-function foolambda (x y)
(
(excl::check-ff-args '((:intinteger
(2147483648
-2147483647))
* :char)
((array character (*))))
(nil x y)
'foo
(with-native-string (#:g158
(if*stringp y)
(
then y""))
else unless (stringp y) (setq #:g158 y))
(symbol-macrolet ((y #:g158))
(load-time-value
(system::ff_funcall (-1
(excl::determine-foreign-address"foo" :language :c)
'(2
nil
nil
16))
'(:intinteger
(2147483648
-2147483647))
x* :char)
'((array
(character
*)))
(
y
'(:intinteger
(2147483648
-2147483647)))))))))
(excl::set-func_name excl::f 'foo)
excl::f))nil 'excl::%fun-documentation)
(excl::put-property 'foo
(record-source-file 'foo) 'foo)12): cl-user(
The new array implementation is discussed in the Arrays and short arrays section in implementation.html. In brief, standard Common Lisp arrays now can be slightly larger than in earlier releases, while the new short arrays implement the old arrays (the same size limitations but also the same type codes and structure).
In this discussion, array' refers to the newly-implemented arrays, while
short array' refers to the old implementation, preserved as short arrays in 7.0.
Foreign calls are made with arrays as arguments by passing the address of the first value. In the new implementation, simple-arrays always have exactly the same first element offset (but some short arrays are aligned to the next higher word boundary so that the elements within are naturally aligned). This sometimes-difference between arrays and short-arrays poses an extra burden on the ff interface, in that the arrays must be distinguished between themselves at runtime.
It is now possible to declare an argument a (short-simple-array ... (*))
and the interface will generate code as it did before for normal arrays, passing the address of the first argument.
For 7.0, a declaration of (simple-array ... (*))
actually generates code that tests at runtime whether the argument is a short array or a normal array. So in effect, a short simple-array passed in as if it were a normal simple-array will be properly passed.
Note that with this setup, if argument checking is specified and a short-array is passed in, the check will fail, because a short-array is not a subtype of simple-array. But for 7.0, if you suppress this argument checking, the interface will pass either array correctly.
However, programmers are urged to provide correct declarations and pass the correct type of array even though 7.0 allows sloppiness. In a future release, we anticipate adding a (dual-simple-array ... (*))
declaration to the direct-call foreign interface, and to move that functionality from its current place in the (simple-array ... (*))
declaration. This would then mean that the (simple-array ... (*))
declaration would only pass simple-arrays, and not short simple-arrays. This change will also make more consistent the arg-checking feature of the direct-call interface, since the dual-simple-array type is defined as an or of simple-array and short-simple-array, so a short-simple-array being passed will pass the test of being a dual-simple-array.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL. See particularly def-foreign-call in foreign-functions.html.
macro, foreign-functions package
Arguments: name-and-options &key type allocation convention
This macro creates the specification which allows Lisp to correctly reference non-Lisp constant data. Like other defining forms, its macroexpansion clearly shows what will occur and at what eval-when times. The execution of the expanded form always returns the Lisp name being defined. The definition that is installed is a symbol-macro that accesses the non-Lisp value correctly.
def-foreign-constant is similar to def-foreign-variable in that the value associated with the name is retrieved from foreign space. It differs, however, in the method of retrieving that value, and extends the types and sizes of values that can be retrieved. def-foreign-constant can resolve foreign structure types as well as integers and floats. But consing of such values is limited because each value is cached only when needed, and the value is stored into the global symbol value slot of the named constant.
name-and-options can either be a symbol or a list of a symbol and an external-name specification. The symbol represents the Lisp-name for which the foreign-variable definition will be installed. The external name specification can be either a string specifying a literal external name, or it can be a symbol, which represents the name of a conversion function. That conversion function must take one required argument and at least the language keyword argument, and must be defined at the time the macro expansion is executed. At that time this conversion function will be called and will receive the Lisp-name specified, as well as the arguments :language lang
where lang is the value of the convention keyword.
type is the access type of the constant, and can be any foreign type (contrast this with def-foreign-variable, which accepts types appropriate for memref and memref-int). The default access type is :unsigned-nat
.
allocation is an allocation type suitable for allocate-fobject. The default value for allocation is :foreign
.
convention is used by the macro to properly translate the Lisp name into a foreign name, and is given to the conversion function as its language keyword argument. The possible values are :c
and :fortran
.
A foreign constant is not constantp, but it is non-bindable and non-settable; attempts to bind or to setq the symbol will result in error. The value is built lazily upon first access to the name symbol, and is thereafter available as the symbol-value of the name. However, if the shared-library that defines the constant is either unloaded or reloaded, or if another shared-library that defines the external-name is loaded, then the foreign-constant is forced to an umbound value, thus starting the lazy instantiation process again.
See foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name definition
Defines name to be a user-defined foreign class with the given definition. And beginning with the 11.0 release, a new type is created, much like defstruct (see the explanation in the example, below). name must either be a symbol or a list beginning with a symbol and followed by attributes (see below). definition is not evaluated and must be a foreign type description as described in The Syntax for Foreign Types in ftype.html.
Like defclass, def-foreign-type returns the class metaobject. The class metaobject can also be retrieved in the usual way by find-class.
The def-foreign-type macro immediately defines the given class in the current Lisp. It also expands into a form that causes that type definition to be made when the resulting form is evaluated.
Note that when a new foreign type is defined in terms of one or more named previously defined foreign types, the new definition is expressed in terms of the current primitive definition of the named types. If the named types are subsequently re-defined, the new type definition will not change. Thus:
nil :int)))
(def-foreign-type one (:struct (
(def-foreign-type two one)nil (:array :int 4)))) (def-foreign-type one (:struct (
The foreign type two
is not affected by the redefinition of the foreign type one
.
Attributes that can be specified are shown below:
Attribute | Type | What |
:pack | integer | worst case alignment needed by data objects. |
:superclass | foreign type name | allows single-inheritance hierarchy of foreign types. |
The :pack
attribute allows a packing of foreign structs that is different than the default pack value which is determined by the size of the objects in the foreign struct.
For example:
1)) (:struct (x :char) (y :int))) (def-foreign-type (foostruct (:pack
Would pack the integer right next to the character, without the normal 3 bytes of padding.
When no :pack
attribute is specified, the general rule is that a structure field that is N bytes long will always be aligned so that its offset from the beginning of the structure is a multiple of N bytes. Extra unused bytes will be added to the structure just before the field if needed to conform to that rule. If a :pack
attribute of K is specified, then the forced alignment will never be to a multiple of more than K bytes. (Only powers of 2 make sense for the :pack
attribute.) Consider the following example:
(def-foreign-type barstruct (:struct (one :long)(two :char)(three :long)))
A :long
is four bytes long, while a :char
is one byte long. This would cause three bytes of padding to be inserted before field three, so that field three is aligned at a multiple of four bytes from the beginning of the structure. Now consider this variation:
2))
(def-foreign-type (barstruct (:pack (:struct (one :long)(two :char)(three :long)))
This would limit the alignment of any field to a multiple of 2 bytes at the most, and so only one unused byte would be inserted before field three to align it to a multiple of two bytes from the beginning of the structure.
Note that the native word size of the machine can affect how structure fields are packed, if a version of Allegro that exploits the native word size of the machine is used. Consider this example:
(def-foreign-type pointerstruct (:struct (one :nat)(two :long)(three :nat)))
The :nat
type indicates the "natural" word length of the machine. When running a 32-bit lisp on a 64-bit machine, however, a :nat
will still be 32 bits. Therefore, when running a 32-bit lisp on any machine, all three fields of that structure will be four bytes long, and no padding bytes will be inserted. But when running a 64-bit lisp on a 64-bit machine, the :nat
fields will be eight bytes long while the :long field will still be four. This will cause four padding bytes to be inserted before field three to align it to a multiple of eight bytes, unlike in a 32-bit lisp. Using a :pack
attribute of 4, on the other hand, would pack the fields in a 64-bit lisp just as it would in a 32-bit lisp.
Normally, a foreign type stands alone and is not related to any other foreign type. But if the :superclass
option is provided then a superclass relationship is established with the given type, which must already be defined. It is a simple hierarchy, similar to C, and single-inheritance only.
Example:
Consider the file fobject.cl, below:
use-package :ff)
(
(def-foreign-type my-point
(:struct (x :float) (y :float)))
(def-foreign-type my-size
(:struct (width :float) (height :float)))
(def-foreign-type (my-rect (:superclass my-point))
(:struct (origin my-point) (size my-size)))
(def-foreign-type (my-box (:superclass my-rect)) my-rect)
Note first that the first two definitions, my-point and my-size, are not hierarchical - they stand alone and have no superclasses.
Next, note that my-rect specifies a superclass of my-point, but not of my-size. That's because my-rect starts out with the same slots as my-point, and can thus be used anywhere my-point can be used, but since my-size is offset in the structure, it can't be a superclass. This is very similar to how defstruct works when its :include
option is used.
Finally, note that my-box consists of only my-rect, and can be used anywhere that a my-rect can be used. But since my-rect has a superclass of my-point, my-box can transitively be used on a my-point as well.
Prior to the 11.0 release, an object allocated with allocate-fobject with an allocation of :foreign
or :foreign-static-gc
would be inconsistent as to what class-of and type-of returns. For example:
5): (setq p (allocate-fobject 'my-point))
cl-user(class my-point>
#<foreign object of 6): (type-of p)
cl-user(3))
(short-simple-array foreign (7): (class-of p)
cl-user(
#<foreign-functions::foreign-structure my-point>8): cl-user(
Note that type-of is returning the basic underlying type of the object that implements it, an array of element-type foreign
, or what we sometimes call a cstruct
. But now, since 11.0:
5): (setq p (allocate-fobject 'my-point))
cl-user(class my-point>
#<foreign object of 6): (type-of p)
cl-user(
my-point7): (class-of p)
cl-user(
#<foreign-functions::foreign-structure my-point>8): (typep p 'my-point)
cl-user(t
9): (typep p 'my-rect)
cl-user(nil
10): (setq r (allocate-fobject 'my-rect))
cl-user(class my-rect>
#<foreign object of 11): (typep r 'my-rect)
cl-user(t
12): (typep r 'my-point)
cl-user(t
Note that what type-of and class-of are returning are now consistent, similar to structs and standard-objects. This slightly incompatible change is not expected to bother anyone; we don't think anyone has used type-of on foreign objects..
Final note:
The implications of the superclass relationship and the type-of change are that CLOS methods can now be defined that can accept objects of foreign-type structs, and the hierarhical nature of the types will allow subclasses of the objects specified to be applicable, as well as the types themselves. For example, based on definitions above:
defmethod foo ((frame my-rect) ...)
( ...)
will accept an object allocated as a my-rect or as a my-box.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL. See in particular the list of types in The Syntax for Foreign Types in that documents.
macro, foreign-functions package
Arguments: name-and-options &key type convention
This macro creates the specification which allows lisp to correctly reference non-lisp variable data. Like other defining forms, its macroexpansion clearly shows what will occur and at what eval-when times. The execution of the expanded form always returns the lisp name being defined. The definition that is installed is a symbol-macro that accesses the non-lisp value correctly.
name-and-options can either be a symbol or a list of a symbol and an external-name specification. The symbol represents the lisp-name for which the foreign-variable definition will be installed. The external name specification can be either a string specifying a literal external name, or it can be a symbol, which represents the name of a conversion function. That conversion function must take one required argument and at least the language keyword argument, and must be defined at the time the macro expansion is executed. At that time this conversion function will be called and will receive the lisp-name specified, as well as the arguments :language lang
where lang is the value of the convention keyword.
type is the access type of the variable, and can be any of the valid access types for memref and memref-int. The default access type is :unsigned-long
. Note the type is not a foreign type.
convention is used by the macro to properly translate the lisp name into a foreign name, and is given to the conversion function as its language keyword argument. The possible values are :c
and :fortran
.
See foreign-functions.html for general information on foreign functions in Allegro CL. The def-foreign-variable section in that documents has more information and examples of def-foreign-variable.
macro, foreign-functions package
Arguments: &rest body
This macro is obsolete and kept for backward compatibility only. Please use def-foreign-type.
This macro defines a C structure to Lisp by defining appropriate accessor and creator functions. The creator function is named make-name. The accessor function names for each slot are the hyphen-separated concatenation of the cstruct name and the slot name.
Argument name is either the name of this cstruct or a list. In the latter case the first element of the list is the name of the cstruct and the second element may be the keyword :malloc
.
Each slot is a list. The first item on the list is a symbol naming the slot, and the rest of the list specifies the datatype. A datatype takes one of the following forms:
:char
:byte
:short
:long
:unsigned-byte
:unsigned-short
:unsigned-long
:short-float
:long-float
This will provide space for the specified atomic C data type to be placed in that slot.
A symbol, which must name a previously defined cstruct.
*datatype where datatype is any valid datatype. As in C, the * indicates that the slot will contain a C pointer (an integer address) to an object of the specified type. Also, as in C, if datatype is a symbol, the requirement that a structure of that name already be defined is relaxed. Pointer slots should normally not contain addresses in Lisp space since Lisp objects may move during garbage collection. They are most useful for C structures created using the :malloc option.
integer [integer...] datatype again, datatype is any valid (possibly compound) datatype, which may include the pointer *. The integers denote an array of the indicated dimensions. The accessor function(s) will accept appropriate subscript argument(s). The subscript arguments follow the C structure argument.
slot [slot ...] cstructs may include other cstructs. Here slot is recursively defined as another list. This is similar to including another cstruct by name.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: lispname &key entry-point unconverted-entry-name arguments pass-types arg-checking prototype return-type language convert-symbol print address remember-address call-direct callback strings-convert
This operator is obsolete and maintained for backwards compatibility only. It has been replaced by the macro def-foreign-call. All new code should use that macro.
This macro defines the calling convention which allows Lisp to call a foreign function correctly, passing arguments of the correct type, and interpreting the returned value correctly. lisp-name is the name (a symbol) by which lisp will refer to the foreign function.
If the entry point (either the value of entry-point or determined by other arguments as described below) does not exist, no error will be signaled when defforeign is called. Instead, the error will be signaled when the function defined by defforeign is called. This makes foreign functions more like Lisp functions -- if you define foo to call the undefined function bar, the error is signaled when foo is called, not when foo is defined.
The function defforeign creates a function identified by lisp-name, which passes its arguments through to the foreign code and returns the return-value of the foreign function to Lisp. The default passing convention (which can be overridden by using the pass-types keyword argument to defforeign) depends on the type of arguments and the language. For example, C normally expects its arguments to be passed by value, Fortran expects arguments to be passed by address.
defforeign returns t
if it successfully defines the foreign function. It returns nil
if it fails.
You can test whether or not an entry point exists with the function get-extern-code-address.
The following are the keyword arguments to defforeign.
Argument | Value | Description |
entry-point | foreign-name | This keyword's value foreign-name
is the name of the entry point as found in the loaded foreign
namespace. If no value is specified, the default depends on other
arguments. The determination of the entry-point need not happen
until the defforeign form is loaded
into (or evaluated within) Lisp and not when a file containing a
defforeign
form is compiled into a fasl
file. If determination of the entry-point is delayed until a
fasl file is loaded, the
same fasl file can be used
on different platforms despite different conventions for naming
entry points (some platforms prepend a _, some append, and some do
not add _'s).
The entry-point name is determined as follows: If entry-point is specified, it is used at compile time. If entry-point is not specified but convert-symbol is, (convert-symbol lisp-name) where convert-symbol is the conversion function given in the keyword argument convert-symbol described below, is used as the entry point at compile time. If neither entry-point nor convert-symbol are specified, unconverted-entry-name is stored at compile time and converted (with convert-to-lang) only when the resulting fasl file is loaded. This allows the same fasl files to be used on various platforms. unconverted-entry-name defaults to the symbol name of lisp-name. Late conversion is the recommended behavior, so neither this argument nor convert-symbol should be specified. This argument and unconverted-entry-name should not both be specified. |
unconverted-entry-name | unconverted-entry-name | unconverted-entry-name should evaluate to a string. The method for determining the entry point name is given in the description of entry-point just above. If a value for this argument is specified, it is stored until the defforeign form defining the foreign function is loaded (or evaluated). At that time, unconverted-entry-name is converted with convert-to-lang to produce the entry-point name. |
arguments | (argument-type+) | This specifies the types of arguments that will be
passed to the foreign function. Its value must be a list of valid
lisp types (e.g. the expressions integer, string, (simple-array
double-float), etc.), or t, which converts arguments according to
their type, whatever they are, or nil ,
which means no arguments. When unspecified, this argument defaults
to t.
The special type |
pass-types | pass-convention+ | This keyword specifies the passing convention of
each argument. The choices are :by-address, meaning pass by
address (Fortran style) and :by-value, meaning pass by value (C
style). The default is the style of the language specified, so
users will rarely have to use this keyword. If the C code passes
arguments by address, however, then this keyword should be used
and its value should be a list of the same length as the argument
list with elements :by-value if the corresponding argument is
passed by value and :by-address if it is passed by address.
In addition to :by-value and :by-address, one can specify :normal and :non-array-by-address. :normal means to use the normal pass-type based on the value of the :language argument. :non-array-by-address means to pass the argument by address if the corresponding argument specified in the arguments list is not an array. |
arg-checking | t-or-nil | This argument defaults to t, in which case Lisp
will check that the arguments passed through to the foreign
function are of the types specified in
arguments. This argument is ignored if
arguments is t. This argument must be nil
if call-direct is
specified t (otherwise the call will not
be inlined). |
prototype | proto | This keyword is now effective on most
platforms. This keyword supports argument passing for machines
with ANSI C compilers which use function argument prototyping. C
functions written with ANSI C prototyping expect arguments to be
passed in a specific format. Before the advent of ANSI C
prototyping, one did not know what format the callee function
expected, so functions always passed in the largest value.
The
default is For example: (ff:defforeign 'blarg :arguments (integer single-float single-float) :prototype (t t)) would say that the first two args are prototyped and the third is not. To use defforeign on a function defined with a prototype, one must list the argument type with the argument keyword and have the prototype keyword argument true. If one has argument checking enabled with the arg-checking keyword argument, then foreign function calling will be strict about getting the correct floating point type. |
return-type | return-type | The value of return-type must be one of the keywords
:integer :fixnum :single-float :double-float :character :lisp :boolean :void :void indicates no value is returned; :lisp indicates a Lisp value is returned
(normally used only if a C program returns a value accessed by the C routine
lisp_value()). The other keywords indicate values of the type named by the keyword. If the
value is :boolean, the function will return When unspecified, this argument defaults to :integer. |
language | language-name | The language-name must be either of the keywords :c, for C, or :fortran, for Fortran. When unspecified, this argument defaults to :c. This argument is ignored if entry-point is specified. |
t-or-nil | If t, information useful for debugging will be printed to *terminal-io*.
This argument defaults to nil . |
|
convert-symbol | con-function | Note: specifying a value for this argument is not
recommended. See the description of
entry-point above for information on how Lisp
determines the entry-point name for a foreign function. If a value
for this argument is specified (and no value is specified for
entry-point or
unconverted-entry-name), the entry-point name
will be determined at compile time by applying the function which
is the value of this argument to lisp-name. The benefits of
determining the entry point only when the fasl file containing the
defforeign
form is loaded (which allows for portability) is lost.
This keyword's value con-function is the name of the function that does the conversion of the Lisp name to an entry-point name. The function must take as arguments a symbol and the keyword :language, and must return a string recognizable to the operating system as an entry-point name. |
call-direct | t-or-nil | The default value of this argument
is nil . If this value
is t , then the compiler will attempt to
inline calls to the foreign function being defined by this call
to defforeign. If the value of
:call-direct is t then the :arguments
keyword argument must be a list of arguments rather
than t
and arg-checking must be
nil (otherwise :call-direct's value will
be ignored). :callback may be t or
nil but if it is t, extra code must be
included to allow for the callback so the inlined call is
slower.
A :call-direct foreign function will return the type specified by :return-type. In earlier releases, a double-float was sometimes returned when :return-type was :single-float. because the C routine returned a double and Lisp did not convert it. Starting in 4.3, Lisp converts the value returned by C if necessary.
Argument types and return types |
callback | callback | Because Allegro CL uses (on some platforms) the
:os-threads model of multiprocessing, it is not
possible to guarantee that Lisp code will not run while a foreign
function defined to Lisp with
defforeign is running
(essentially what :callback nil did in earlier relases on
Unix). Therefore, whatever is specified for this argument, t is the value used. See the
release-heap keyword argument of
def-foreign-call. |
method-index | nil (the default) or an index into C++ table, as described at
right. |
This argument allows for calling of C++ style member-methods. The value, if specified, must be an integer index into the virtual table of the C++ class. Symbolic index specifications are not directly supported. |
strings-convert | nil
or t . Default
is t . |
This argument is only supported on 16-bit
character Lisps. (Allegro CL can run with 8-bit characters or
16-bit characters. See
this section
of startup.html for the various Allegro CL
images.) This argument assists in having the foreign-function
interface handle Allegro CL's 16-bit strings automatically. When
the strings-convert is true, then when any of
the specified arguments at
defforeign time are declared
directly or indirectly as (*
:char) , defforeign
augments the
function wrapping the low-level foreign function call so that for
each (* :char) declared argument, a check is
made at runtime to see if that declaration's corresponding value
is a string. If it is, then that value is converted at runtime to
native-string format using a dynamic-extent array, and this new
array is passed in place of the original string argument to
low-level foreign function call. See
Foreign-Functions
in iacl.html for full details and examples (the
examples use def-foreign-call. |
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: forms &key print
This function is obsolete and maintained for backwards compatibility only. There is no real equivalent in the redesigned interface. defforeign has been replaced by the macro def-foreign-call. All new code should use that macro, calling it repeatedly if a number of foreign functions must be defined.
This function allows you to define many foreign functions at once. It may be more convenient but it is no faster than calling defforeign many times. This function returns the number of unsuccessful definitions so a returned value of 0 means that all definitions were successful. The following definition is functionally equivalent to the definition of defforeign-list.
defun simple-defforeign-list (list-of-arg-lists)
(let ((errors 0))
(dolist (arg-list list-of-arg-lists errors)
(unless (apply #'ff:defforeign arg-list)
(incf errors))))) (
Each arg-list argument must be a list of the arguments that would be passed to defforeign. Note that the individual lists are processed in an apply form and thus the elements in the individual lists are not evaluated as they would be if the same values were passed directly to defforeign. For example, if you want elements of the lists evaluated, you must backquote the entire list of arg-lists and put commas before those elements which require evaluation.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name arglist &rest body
This macro is obsolete and has been replaced by defun-foreign-callable. Please use that macro in all new code. This macro is maintained for backward compatibility only.
This macro defines a function in Lisp that can be called from foreign (traditionally C) code.
The argument list can be restated as:
lisp-function-name ({arg | (arg type)}*) body-form+
Thus arglist (the second argument in the argument list) is a list of arguments each of which is either a symbol (as in the usual function definition), or it is a list of length two, a symbol and its type. If a symbol only is present, then it has the default type (:signed-natural
). Each is an argument which C passes to Lisp. This macro does not allow &rest or &optional arguments in the argument list. The type corresponds to a memref type (see memref and memref-int) and is limited to be one of the following:
:signed-byte 8 bits
:unsigned-byte 8 bits
:signed-word 16 bits
:unsigned-word 16 bits
:fixnum 30 bits
:signed-long 32 bits
:unsigned-long 32 bits
:signed-natural (the default)
:unsigned-natural
:single-float, single-float 32 bits
:double-float, double-float 64 bits
:lisp (Assumes that C passes an actual Lisp value)
Warning for users of 64-bit Lisps: :signed-long
and :unsigned-long
are treated as 32-bit values, even on a 64-bit port. Contrast this to defun-foreign-callable, where :long
and :unsigned-long
match the precise meaning in C on the architecture in question. But note further that that does not mean they follow the 32/64-bit nature of the Lisp; for example, a :long
foreign type on Compaq Alphas is always 64-bits, even for a 32-bit lisp. But this is consistent with C.
See memref and memref-int and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: name arglist &rest body
This macro creates a function that can be called from non-Lisp code. It is intended that such a function be callable from Lisp as well, but such functionality has not yet been provided. (This macro replaces the obsolete defun-c-callable.)
name must be a symbol representing the name of the new function to install.
arglist is an argument list specification. Each argument is either a symbol representing the name of an argument of type :long
, or it is a list of two elements containing the argument name and foreign-type, respectively. See The Syntax for Foreign Types in ftype.html for information on pre-defined foreign types. Other foreign types can be defined with def-foreign-type. (arg-name (:aligned ftype))
is not supported though (arg-name :aligned)
is. The :lisp
type is also supported (meaning a Lisp object is passed from the foreign code to Lisp) but see the warning below.
If the foreign type represents a :struct
, :union
, or :class
, it creates possible pass-by-value semantics, based on the current value of *pass-structs-by-value* or the value given to the :pass-structs-by-value
option.
If you specify an argument to be of type :lisp -- like (arg-name :lisp)
-- a warning will be signaled because doing so casually is dangerous. Unless the Lisp value is an immediate (for example, a fixnum or a character), it is actually a pointer which is passed to Lisp. If that pointer happens to be to an object which has been moved by the garbage collector, then it will be invlaid and may cause Lisp to fail with a gc error.
The warning can be suppressed with the :lisp-args-will-not-move declaration:
3): (ff:defun-foreign-callable foo ((x :double) (y :lisp)))
cl-user(
Warning: While defining foo: for foreign callback-arg named y,type for a transition from
specifying :lisp as a foreign lisp space is dangerous because the object may move
foreign to the object is an
due to an intervening garbage collection. If the :aligned
aligned address consider instead using if the object is static or if
specification. Otherwise,
careful analysis shows that no movement can possibly occur,the :lisp-args-will-not-move option in the definition
then add remove this warning.
in order to
foo4): (ff:defun-foreign-callable foo ((x :double) (y :lisp))
cl-user(declare (:lisp-args-will-not-move t)))
(
foo5): cl-user(
Specifying the type as :aligned
will not signal a warning. Manipulating :aligned
values (which look like fixnums to Lisp) is complicated and aligned pointers can also be moved, but that is uncommon. See Aligned Pointers and the :aligned type in ftype.html.
The first form in the body can be a declaration form, whose valid options are :convention
, :unwind
, and :returning
; something like:
(defun-foreign-callable my-callback ()declare (:convention :c))
( ...)
The possible values of the options are:
:convention
: the convention provides for the specialization of calling conventions due to language or operating-system distinctions. The default convention is :c
, and is adequate for most situations. :fastcall
is also accepted. Other values are distinguished by MS Windows-based systems including :stdcall
, :method
, and :fastcall
, but :fastcall
is not supported and should not be specified. See Note 2: Possible Values for Convention on the page for def-foreign-call.
:unwind
: on MS Windows based systems, defaults to 0, and to nil
on all other systems. May be nil
or an integer.
:pass-structs-by-value
. This causes the *pass-structs-by-value* variable to be set (after it has been bound to its own value at the beginning of the macro call) to the value given. The valid values are nil
, :warn
, and t
.
:returning
: this specifies the type of what is returned by the called function. It is ignored except when the declared value includes a foreign struct type (either a :struct
, a :union
, or a :class
). Those can be passed by reference or by value depending on the value of *pass-structs-by-value* and the value given to the :pass-structs-by-value
option. If passing is by reference, a hidden argument is provided and the structure is arranged to be copied back to the caller, according to the calling convention of the architecture. The general form is
(ff:defun-foreign-callable foo (...)declare (:returning <type>))
( ...)
where <type>
is a foreign type or its name specifying a structure. This declaration is intended to eventually replace the convert-to-c-types argument in register-foreign-callable, and cannot be used with it.
New C++ and other language based systems tend to establish exception handlers, and set up their own equivalent of unwind-protects in their own langage. Lisp knows nothing about such exception handlers, and thus tends to trash the handler chains that have been built up whenever lisp code throws over non-lisp code to a catch form in lisp code deeper in the stack. The non-lisp code had been expecting either its own exception handling system to remove the exception from the chain on the stack, or else normal functional returns to unwind the stack in a normal fashion.
When the :unwind
value is nil
, then no special unwinding takes place. When the argument is non-nil
(e.g. 0), then a special "throw-by-returning-to-c" style of unwinding occurs; a throw occurs, not by removing the stack (including the foreign code which might have established handlers), but instead by returning the unwind-value to that code, which should then remove its own handler and return. When the foreign code returns, the lisp throw is again resumed until it is completed, or until the next lisp-to-nonlisp transition is encountered.
In order to use a function defined by defun-foreign-callable, the function must first be registered using register-foreign-callable.
What the foreign-callable function returns as a foreign value is controlled by the call to register-foreign-callable (which actually enables the foreign callable function). If the third (optional) argument to register-foreign-callable is nil
, an unconverted Lisp value is returned in the foreign return register. Programmers must use the specifications in [Allegro directory]/misc/lisp.h to interpret this value. If the third argument is t
, then the Lisp value of the function is converted to a foreign value according to the default conversion rules, and the resulting value is returned as the foreign value returned by the Lisp function.
The body of the foreign callable Lisp function must be carefully coded to return a Lisp value that will trigger an appropriate conversion so that the desired foreign value will actually appear at the interface.
Consider this call to defun-foreign-callable:
string (* :char)))
(defun-foreign-callable gdbm-error-handler ((error "gdbm error: ~a." (native-to-string string))) (
The call native-to-string is necessary because the string argument in the callback to Lisp is done with no string conversion at callback time. The value of the string argument as passed will be an integer representing a C address. native-to-string does the necessary conversion.
Fwrapping (see fwrappers-and-advice.html) and thus tracing (see The tracer in debugging.html will now work on foreign-callable functions.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: fobject &optionsl ftype
This function prints a description of the contents of a foreign object. If the object's allocation type is :foreign
or :foreign-static-gc
, then the ftype argument should not be given. If the allocation type is :lisp
, :lisp-short
, or :c
then the ftype argument must be given to specify the type of the object.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: &key name definition
This is the functional equivalent of def-foreign-type.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: eucvector &optional address
ff:euc-to-char* is obsolete. octets-to-native should be used instead. See also with-native-string. Using octets-to-native means fewer modules need be present in an image using this functionality. ff:euc-to-char* is defined in the :ffcompat
module which is not present in an image by default.
This function converts a Lisp (simple-array (unsigned-byte 8) 1) of EUC characters to a C string by copying. If address is specified, then that address is used. Otherwise, the system malloc (memory allocator) is used to make space for the target (char *) string.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: object &optional allocation
This function returns t
if object is appropriate as an argument to foreign type accessors. allocation can be :foreign
(the default), :c
, :lisp
or :lisp-short
.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
The use of this function is deprecated because the value it returns may not be valid after a dumplisp and may not be valid if the foreign function is redefined by loading a modified (or new) so/sl/dll file. In the presence of multiprocessing, such a redefinition can in theory happen at any time. (In a non-SMP Lisp, you can protect against unexpected redefinitions by preventing other processes from running. That is much, much harder in an SMP Lisp.)
This function returns the foreign address of function. function should be a function defined by defforeign or def-foreign-call. The address of the entry point of the foreign function in the foreign code is returned. If foreign-address cannot find a foreign address for function, then an error is signaled.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: object
Returns true for integers, arrays, and foreign-pointer instances. These are lisp objects for which it makes sense to convert into some kind of C address when passed into C via a foreign-function call.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
generic function, foreign-functions package
Arguments: fp
Accessor for the non-lisp address within a foreign-pointer. setf'able. See make-foreign-pointer.
Note that the non-lisp address accessed by foreign-pointer-address is not stored as a CLOS slot. Instead it is stored in an extra location in the instance which is not touched by the garbage collector. This address can be seen by inspecting the instance with the :raw t
option. See inspector.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
generic function, foreign-functions package
Arguments: object
Returns t if the argument is an instance of the foreign-pointer class.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
generic function, foreign-functions package
Arguments: foreign-pointer
Accessor for a slot in a foreign-pointer instance. The default value is the value specified by the :foreign-type
initarg specified in a call to make-foreign-pointer. setf'able.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: address
Use of this function is deprecated. Please use char*-strlen. See the documentation for that function, as this function works exactly the same way. This function is defined in the :ffcompat
module (which is not included in the image by default).
function, foreign-functions package
Arguments: type
This function returns how much prepadding is done for a :lisp
allocated instance of the argument type. The type can be a symbol naming the type or an expression to define the type, as in:
(ff:foreign-type-lisp-pre-padding '(:struct (a :int) (b :double)))
:lisp
allocated foreign structures are allocated in Lisp arrays of element type (unsigned-byte 8)
. Due to alignment requirements of the structure being defined and of the processor on which Lisp is running, some structures may be stored in the Lisp array beginning at an index other than zero.
For example this type, created by a call to def-foreign-type,
(def-foreign-type foo (:struct (d :double) (i :int)))
will start at index 4 in the Lisp array when running on the Sparc processor but at index 0 in the Lisp array when running on the Intel x86 architecture. foreign-type-lisp-pre-padding applied to (:struct (d :double) (i :int))
, thus, returns 4 when run on an Intel x86 box and 0 when run on a Sparc box.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
name must be a symbol. If name is the name of a foreign type defined with def-foreign-type, then t
is returned.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: obj
This function is obsolete. Please use allocate-fobject to allocate foeign objects (instead of make-cstruct or creators defined by defcstruct and def-c-type). Please use free-fobject or free-fobject-aligned to free them in place of this function. This function is maintained for backward compatibility.
obj must be the address of an object in foreign space created with make-cstruct or equivalent. This function frees the space allocated for the object.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: fobj
Free an object that was allocated by allocate-fobject with the :c
. An object should only be freed once.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: fobj
Free an object that was allocated by allocate-fobject with the allocation of :aligned. An object should only be freed once.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Function, foreign-functions package
Arguments: object
Free an object that was allocated by allocate-fobject-c. An object should only be freed once.
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to a free-fobject call as quickly as possible.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: object
Free an object that was allocated by allocate-fobject-fp. An object should only be freed once.
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to remove the call to free-fobject-fp, allowing the object to be garbage collected eventually. (This applies to the normal case where the object is created by a call to allocate-fobject-fp, which expands to a call to allocate-fobject with an allocation of :foreign-static-gc
; if instead the object is allocated by a call to allocate-fobject with an allocation of :c
, then free-fobject may be called to free it.)
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: object &rest slot-names
The arguments to this function are like those of fslot-value, but this function returns a Lisp integer that represents the address of the slot instead of the value in the slot.
It is like fslot-address-typed, but works only for :foreign
or :foreign-static-gc
objects. It cannot be open coded by the compiler. Please see the caution in description of fslot-address-typed about using the returned address value.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: type &rest args
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to a fslot-address-typed with allocation argument :c
.
type should be an object created by allocate-fobject-c.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: type &rest args
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to a fslot-address-typed with allocation argument :foreign-static-gc
. type should be an object allocated with allocate-fobject-fp.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: type allocation object &rest slot-names
This function is a synonym for fslot-address-typed. Use of this function, maintained for backward compatibility, is deprecated.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: type allocation object &rest slot-names
The arguments to this function are like those of fslot-value-typed, but this function returns a Lisp integer that represents the address of the slot instead of the value in the slot.
The value of the allocation argument can be a keyword specifying the storage class (the values are described below) or nil
, in which case the allocation will be computed from the object argument (but see the warning about allocation values which are not recommended).
If the allocation of the object is :foreign-static-gc
or :c
, then the integer address may be used to access the interior of the object. If allocation is not nil
and all the slot names are constants, then this function will be open coded by the compiler if the optimize-fslot-value-switch is true.
Other accepted values for allocation are :foreign
, :lisp
, and :lisp-short
, but specifying those values is not recommended because the returned address may already be or may become invalid since the referenced object may be moved by the garbage collector after the address has been computed (and even before it is returned by this function), making the address meaningless. If the returned integer is used as an address in a memory reference, it is possible to reference non-existent memory, or to damage a random unrelated location in memory.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: object &rest slot-names
This is like fslot-value-typed except it can only be used to access slots from objects with :foreign or :foreign-static-gc allocations, since these are the only objects that are runtime typed.
This function is a lot more convenient to use than fslot-value-typed since the type and allocation needn't be specified, however it can't at present be open coded. Thus for speed critical parts of the program, fslot-value-typed should be used.
When the accessed slot is a primitive type, then the value of the slot is returned. When the accessed slot is a composite type such as a sub-structure or an array, then the address of the sub-structure or array is returned as a Lisp integer. Please see the caution in description of fslot-address-typed about using the returned address value.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: type &rest args
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to a fslot-value-typed call. (Use the allocation argument of fslot-address-typed to specify where the allocation should occur. Specify :c
for allocation to get behavior equivalent to this macro.)
type should be an object created by allocate-fobject-c.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: type &rest args
This function is defined by the ACLWIN compatibility package. It is loaded with
require :aclwffi) (
However, it is for compatibility with Allegro CL 4.3.2, an early release of the UNIX product on Windows which had limited distribution, not compatibility with Allegro CL 3.0.x on Windows.
This function is provided for porting from Allegro CL 4.3.2 only and users with 4.3.2 code calling this function are urged to convert the call to a fslot-address-typed call. (Use the allocation argument of fslot-address-typed to specify where the allocation should occur. Specify :foreign-static-gc
for allocation to get behavior equivalent to this macro.)
type should be an object created by allocate-fobject-fp.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: type allocation object &rest slot-names
Accesses a slot of a foreign object. setf may be used with this function to change the value in the slot. (The setf is like that of fslot-value, but the type and allocation arguments are also specified. There are examples below and in ftype.html.)
The type argument declares the type of the object being accessed. (When an object that is embedded within or pointed to by another object is being accessed, then this is the type of the outermost object, and the type does not need to be declared for the inner objects.) It may be:
a symbol naming a foreign type.
a type description using the syntax shown in The Syntax for Foreign Types in ftype.html.
a foreign type object, that is a foreign class metaobject, such as is returned by def-foreign-type, find-class, or class-of.
The allocation argument declares the storage class of the object being accessed. allocation must be one of :foreign
, :foreign-static-gc
, :lisp
, :c
, :aligned
or nil
. If the allocation is nil
then the allocation type will be computed from the object argument. When the allocation argument is not nil
, and the slot names are all constants, then this function will be open coded by the compiler if the optimize-fslot-value-switch is true.
The object argument identifies the object being accessed. The following table shows what object should be given the value of allocation:
Allocation argument | Object argument |
:foreign |
A foreign object allocated in the Lisp heap |
:foreign-static-gc |
A foreign object allocated in the Lisp static memory |
:lisp |
A Lisp array of type (unsigned-byte 8) of sufficient size to hold the foreign object. |
:lisp-short
|
A Lisp short-array of type (unsigned-byte 8) of sufficient size to
hold the foreign object. This type is otherwise the same as the
:lisp type described just above, except that the
data is held in a short-array. (short-arrays are a new data type
corresponding to the older array type in Allegro CL. See
Arrays and short
arrays section in < href="implementation.html">implementation.html.)
|
:c |
A Lisp integer representing the address of the object in memory. |
:aligned |
A Lisp integer representing the aligned address of the object in memory. |
nil |
Any of the four types above. |
The slot-names are symbols or integers. Symbols name the slots to access. Integers are used to specify array indices.
The symbol naming a slot can either be the exact symbol used when the type was defined, or it can be a keyword package symbol with the same symbol-name as the one used to define the slot.
When the accessed slot is a primitive type, then the value of the slot is returned. When the accessed slot is a composite type such as a sub-structure or an array, then the address of the sub-structure or array is returned as a Lisp integer. Please see the caution in the description of fslot-address-typed about using the returned address value.
The special slot-name asterisk is used to denote dereferencing a pointer. If a slot has the type ( foo) then you use the * slot name to indicate that you want to follow the pointer to the foo-typed object. If the object is an array, then the asterisk will access the first element of the array (the element at index zero).
When the allocation argument is not nil
, and the slot names are all constants, then this function will be open coded by the compiler if the optimize-fslot-value-switch is true.
setf can be used with this function to change the value.
;; Here are some general examples. We create foreign types and
;; allocate some instances (we do not specify any values, so
;; the values you see if you do this are defaults or meaningless
;; data.
(def-foreign-type sub-rec (:struct (a :int) (b :int)))
(def-foreign-type record-date
(:struct
(day :int)
(month :int)
(year :int)))
(def-foreign-type record
(:struct
(num1 :int)
(num2 :int):array :int 17))
(nums (:array :float 11 12))
(floats (
(internal sub-rec)* record-date))
(pointer (:array sub-rec 7))
(sarray (
))
setq x (allocate-fobject 'record))
(
setq rd (allocate-fobject 'record-date :c))
(
nil x 'num1)
(fslot-value-typed 'record the integer value of slot num1
RETURNS
nil x 'nums 3)
(fslot-value-typed 'record the integer value of element 3 of
RETURNS the array at slot nums
nil x 'floats 5 7)
(fslot-value-typed 'record the float indexed with 5 and 7 in
RETURNS the array at slot floats
nil x 'internal)
(fslot-value-typed 'record integer that represents the
RETURNS an the sub-structure.
address of
nil x 'internal 'a)
(fslot-value-typed 'record the integer value of slot a of
RETURNS the sub-structure of type sub-rec at slot internal
nil x 'pointer)
(fslot-value-typed 'record the address in slot pointer
RETURNS integer that can be used with the
This address is an type :c to access data stored at
allocation the pointer location
setf (fslot-value-typed 'record nil x 'pointer) rd)
(
nil x 'pointer '* 'year)
(fslot-value-typed 'record the integer value of slot year in the instance
RETURNS type record-date stored at the address in slot pointer
of
nil x 'sarray 3 'b)
(fslot-value-typed 'record the integer value of slot b in the structure of
RETURNS type sub-rec that is stored as element 3 of the array
at slot sarray
In the last example above, we specified that the top-level foreign object being accessed is a record
structure, but it was not necessary to also state that the lower-level object in its sarray
slot is an array of sub-rec
structures. The reason is that this information is declared in the def-foreign-type for the record
structure, and so the compiler can derive that information from there. In some cases, however, the top-level foreign object may not define the types of its subobjects, such as when it is an array of pointers to other arrays. In such cases, the type argument to fslot-value-typed may be a nested list that specifies the type of the top-level object as well as its subobjects. See The Syntax for Foreign Typesin ftype.html for the complete definition of Allegro's foreign type format.
For example, in the following function, which asks GTK for all of its available font faces, the GTK function pango_context_list_families fills in a longword (which we have passed to it) with a pointer to a vector of pointers to GTK PangoFontFamily objects. To access each font family, the call to fslot-value-typed near the bottom specifies the foreign type as the nested list (* (:array (* PangoFontFamily)))
, indicating that we are accessing a pointer to an array of pointers to PangoFontFamily objects.
(Common Graphics on GTK is no longer supported, but this example remains as a general example.)
To be precise, the simpler expression (* (:array :long))
would have worked just as well here, because the nested expression (:array :long)
would still tell lisp what sort of object the final "j" slot argument is accessing, but (* :long)
is not sufficient for that.
defun available-gtk-font-families (&optional pango-context)
(
(with-stack-fobjects* (:array (* PangoFontFamily))))
((array-pointer '(:array gint 1)))
(count-integer '(
(pango_context_list_familiesor pango-context (gdk_pango_context_get))
(
array-pointer count-integer)do* ((faces nil)
(count (fslot-value-typed '(:array gint 1) nil
(0))
count-integer 0 (1+ j)))
(j >= j count)
((sort faces #'string<))
(push (native-to-string
(
(pango_font_family_get_name* (:array (* PangoFontFamily)))
(fslot-value-typed '(nil array-pointer 0 j)))
faces))))
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
This function returns two values. The first is the entry point for name, which must be a string. nil
is returned if name does not have an entry point.
The second returned value is the handle of the .so/.sl/.dll/.dylib library in which the symbol was found.
For example, "aclmalloc" is the name of the C function called by aclmalloc. Using this function, we find its entry point is 1872778976 and the handle of its library is 4. Using get-shared-library-handle and get-shared-library-name, we find it is in the Allegro CL shared library called (on this machine and in this run) "libacli61pf4.so" (the name you see will be different).
101): (ff:get-entry-point "aclmalloc")
cl-user(1872778976
4
102): (get-shared-library-handle)
cl-user(4
103): (get-shared-library-name)
cl-user("libacli61pf4.so"
104): cl-user(
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: *names addresses &optional debug &key return-missing-stub-address
This function is obsolete and use is not recommended. Use get-entry-point instead. In fact, this function just calls get-entry-point repeatedly.
This function takes a vector of names, each a string, and finds the memory address of each name inside the running Lisp process. The address of the ith name is put in the ith position of addresses, which must be of type
simple-array (unsigned-byte 32) (*)) (
on some platforms and of type
simple-array (unsigned-byte 64) (*)) (
on others. Because of this incompatibility between platforms, we do not recommend that this function be used. Instead, entry points should be gotten one at a time with get-entry-point.
If a name is not found, the address is filled with the value of *impossible-load-address*. The function returns the number of unmatched names in the names. The print argument is a Boolean variable (default nil
), which, if true, will print useful information to the operating system standard output.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
This function is obsolete and maintained for backward compatibility only. It is essentially the same as get-entry-point.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
This function is obsolete and maintained for backward compatibility only. It is essentially the same as get-entry-point.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name-or-ftype &optional errorp
Returns an internal structure containing a description of a foreign type. This internal structure can be passed to those functions that take a foreign type name (such as allocate-fobject).
This function is useful when the foreign-type is a type description, such as (:array :int 10)
, that must be parsed each time it is used in a function such as allocate-fobject. By calling get-foreign-type once on (:array :int 10)
to create the internal description, and then passing that internal description each time to allocate-fobject, that will save the parsing cost on each call.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: index
This returns the value in the table of registered values (see register-lisp-value) at the given index.
This function is setf'able. Thus, one can replace slots in the foreign values table.
This function is the Lisp equivalent of the C function lisp_value provided for referencing Lisp values from foreign code. See Accessing Lisp values from C: lisp_value() in foreign-functions.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: &rest keys &key return-structs &allow-other-keys
Returns a list of all foreign-libraries that are loaded into the current lisp image. Keywords remain undocumented, but a useful keyword in many architectures is return-structs, which when true cause a list of structures to be returned with more information than just the library names.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &key number in-foreign-space initialize
This function is obsolete. Please use allocate-fobject to allocate foeign objects. Please use free-fobject or free-fobject-aligned to free them in place of free-cstruct. This function is maintained for backward compatibility.
This function returns a new instance of the C type (it does not have to be a struct) named name, which must have already been defined with def-c-type or defcstruct. Both ordinary and foreign space types may be created with this function.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: &key foreign-address foreign-type size aligned address type
Creates and returns a foreign-pointer object. These objects are designed to hold integer addresses and in most cases, an integer works as well as a foreign-pointer object. An advantage of foreign-pointer objects is simply that they are different from an integer, allowing for better checking. And because it is an instance of a CLOS class, it can be extended in the normal CLOS way.
foreign-address is the C address that is being pointed to; foreign-type is a user-specifiable type that becomes the value of the foreign-type slot of the foreign-pointer instance being created. size causes allocation of foreign space of that size. Typically, only one of the size and foreign-address keyword arguments is specified. size is ignored if foreign-address is specified.
If aligned is true and the address or foreign-address keyword was given, then the address is interpreted as an aligned address and is shifted to become a machine integer before storing. (Aligned pointers are described in Aligned Pointers and the :aligned type in ftype.html.)
It is an error if both size and foreign-address are unspecified.
address and type are obsolete and should not be used. They are variants of foreign-address and foreign-type. If adress is specified, the value should be as for foreign-type. You should not specify both address and foreign-address.
See foreign-pointer-address, foreign-pointer-type, and foreign-pointer-p.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &key initialize
This function is obsolete. Please use allocate-fobject to allocate foreign objects. Please use free-fobject or free-fobject-aligned to free them in place of free-cstruct. This function is maintained for backward compatibility.
This function creates a type in foreign space. The type named by name, which must already have been defined with def-c-type or defcstruct as a type in foreign or malloc space.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &optional index-or-reuse convert-to-c-types
The name argument must be a symbol defined with defun-foreign-callable.
The index-or-reuse argument can be a fixnum to select a specific table entry to replace, or the symbol :reuse
to specify that if a function with the same name is already registered, the function will be replaced at the same index.
If convert-to-c-types is specified, then an attempt will be made to convert the return value to a foreign value, otherwise the return value is returned unchanged. It is important to note that though the default is nil
, most often the desired effect is obtained by setting this option to t
. The default of nil
is retained for compatibility reasons. This is described in a little more detail in the description of defun-foreign-callable.
This function returns 5 values:
In versions using the :os-threads model of multiprocessing, the callback from foreign code to the foreign-callable function name may be made from a thread started outside Lisp. This is not supported in a version of Lisp using the non :os-threads model of multiprocessing. trying it will likely cause Lisp to fail. See Foreign functions and multiprocessing in foreign-functions.html.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: foreign-callable &optional index-or-reuse convert-to-c-types
This function has been renamed register-foreign-callable. Please use that name in new code. This name is maintained for backward compatibility only. The description of register-foreign-callable says:
The name argument must be a symbol defined with defun-foreign-callable.
The index-or-reuse argument can be a fixnum to select a specific table entry to replace, or the symbol :reuse
to specify that if a function with the same name is already registered, the function will be replaced at the same index.
If convert-to-c-types is specified, then an attempt will be made to convert the return value to a foreign value, otherwise the return value is returned unchanged. It is important to note that though the default is nil
, most often the desired effect is obtained by setting this option to t
. The default of nil
is retained for compatibility reasons. This is described in a little more detail in the description of defun-foreign-callable.
Returns 5 values
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: value &optional index
The value is stored in the table of foreign values at the requested index, if index is given; or in a free slot if index is not given. Two values are returned: the index and the previous value at that index (or nil
if there was no previous value at that index).
Note that there is a distinction between registering a symbol and its value. To register the value of a symbol, one wants to evaluate the symbol. To register the symbol object itself, one must quote it. Thus
(ff:register-lisp-value 'my-symbol)
registers the symbol my-symbol
, whereas
(ff:register-lisp-value my-symbol)
registers the (current) value of my-symbol
. If one registers the value of a symbol and subsequently the value is changed, the change will not be reflected in the value returned by lisp_value() in C (described in foreign-functions.html). If one registers a symbol, one must use special macros in C to access the value of the symbol.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: value &optional index
This function has been renamed register-lisp-value. The old name is maintained for backward compatibility. New code should use the new name.
The value is stored in the table of foreign values at the requested index, if index is given; or in a free slot if index is not given. Two values are returned: the index and the previous value at that index (or nil if there was no previous value at that index).
Note that there is a distinction between registering a symbol and its value. To register the value of a symbol, one wants to evaluate the symbol. To register the symbol object itself, one must quote it. Thus
(ff:register-value 'my-symbol)
registers the symbol my-symbol, whereas
(ff:register-value my-symbol)
registers the (current) value of my-symbol. If one registers the value of a symbol and subsequently the value is changed, the change will not be reflected in the value returned by lisp_value() in C (described in foreign-functions.html). If one registers a symbol, one must use special macros in C to access the value of the symbol.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name &optional print data
This function is obsolete. In earlier releases on Unix where foreign code was actually loaded in Lisp (rather than being in a shared-library which is linked), Lisp would build a symbol table to keep track of locations. This function would remove an entry from the symbol table. However, since no version of Allegro CL uses that model of foreign loading, this function is effectively a no-op and should be removed from code that uses it.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
This function is obsolete. In earlier releases on Unix where foreign code was actually loaded in Lisp (rather than being in a shared-library which is linked), Lisp would build a symbol table to keep track of locations. This function would remove an entry from the symbol table. However, since no version of Allegro CL uses that model of foreign loading, this function is effectively a no-op and should be removed from code that uses it.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: name
This function is obsolete. In earlier releases on Unix where foreign code was actually loaded in Lisp (rather than being in a shared-library which is linked), Lisp would build a symbol table to keep track of locations. This function would remove an entry from the symbol table. However, since no version of Allegro CL uses that model of foreign loading, this function is effectively a no-op and should be removed from code that uses it.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: ftype
This function returns the size of an object of the given foreign type. The argument ftype can be an ftype or a name of a foreign type or certain kinds of fobjects. (fobjects are the objects that result from a call to allocate-fobject and related functions.) Only fobjects of allocation type :foreign
or :foreign-static-gc
can be arguments to this function. fobjects of allocation types :lisp
, :lisp-short
, :c
, and :aligned
cannot be arguments. The allocation type is defined when the object is created. Note that objects of allocation type :lisp
have their own lisp types, and thus do not imply a foreign-type; and objects of :c
allocation are just integers, and thus again do not imply a foreign-type.
The size only includes the data bytes and not any overhead bytes needed by lisp.
1): (ff:def-foreign-type point (:struct (x :int) (y :int)))
cl-user(
#<foreign-functions::foreign-structure point>2): (setq obj (ff:allocate-fobject 'point :foreign-static-gc))
cl-user(class point>
#<foreign object of 3): (ff:sizeof-fobject 'point)
cl-user(8
4): (ff:sizeof-fobject (ff:get-foreign-type 'point))
cl-user(8
5): (ff:sizeof-fobject obj)
cl-user(8
6): cl-user(
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: string &optional address
This function is obsolete. It has been replaced by string-to-native. A call to string-to-char* has been changed to return the first value of the following:
(excl:string-to-native *string*
:address *address* :default) :external-format
Users are encouraged to use string-to-native instead of string-to-char* for new code. See also native-to-string and with-native-string.
The remainder of this description is the old documentation for string-to-char*.
This function returns an integer pointer to a C string. string should be a Lisp string. If the optional address argument is used, then string-to-char* copies string to address.
This function uses malloc to allocate the space needed for the string. This space will not be freed automatically by Lisp. Users must free the space themselves, by calling aclfree with the address returned by string-to-char* as the single argument.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: string &optional address
Use of string-to-wchar* is deprecated. Please use string-to-native instead. Using string-to-native means fewer modules need be present in an image using this functionality. ff:string-to-wchar* is defined in the :ffcompat
module which is not present in an image by default.
ff:string-to-wchar* returns the following:
string
(excl:string-to-native 16-bit) :address <em>address</em> :external-format :
Users are encouraged to use string-to-native instead of ff:string-to-wchar*. See also with-native-string. This function converts a Lisp string to a C style fat format string by copying. If address is specified, then that address is used. Otherwise, the system malloc (memory allocator) is used to make space for the target character array.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: pathname
If the shared-library represented by pathname is loaded (using pathname-equalp to test) it is then unloaded, causing further foreign calls to functions in that library to behave as if the library had never been loaded.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: index
Removes the function registered in the index'th entry in the table of foreign-callable functions. Functions that can be registered are defined with defun-foreign-callable and registered with register-foreign-callable.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: index
This function has been renamed unregister-foreign-callable. The old name is maintained for backward compatibility.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: index
Clears the slot in the table of registered values identified by index. The garbage collector will clear the associated value if there are no other pointers to it within Lisp. See register-lisp-value.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: index
This function has been renamed unregister-lisp-value. The old name is maintained for backward compatibility. New code should use the new name.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
function, foreign-functions package
Arguments: address
Use of this function is deprecated. Please use short*-wcslen. See the documentation for that function, as this function works exactly the same way. This function is defined in the :ffcompat
module (which is not included in the image by default).
The primary name of this function was changed so that fewer modules need be present in an image using this functionality. Further, wchar*' is actually a misleading name because some architectures define
wchar' as a object with more than 16 bits, while all define `short*' as a 16-bit entity, which is what we intend by the name.
function, foreign-functions package
Arguments: address
Use of wchar*-to-string is deprecated. Please use native-to-string instead. Using native-to-string in place of this function requires fewer modules in the image. ff:wchar*-to-string is defined in the :ffcompat
module which is not present in an image by default.
wchar*-to-string function converts a C style wide-char (16-bits / character) string to a Lisp string by copying. The source string is assumed to be null-terminated by two zero octets (i.e., a 16-bit zero).
This function is equivalent to the following
(native-to-string address :external-format :fat)
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: (var type &key allocation size) &rest body
This macro allocates a foreign object of the specified type, allocation, and size, and binds it to var while evaluating body. The body is evaluated inside a lexical binding of var. Withing the body, the object may be accessed using fslot-value with the same allocation argument. The default allocation is :foreign
. Under the right circumstances (described below) the object may be allocated on the stack.
The allocation argument defaults to :foreign
, and can be one of :c
, :aligned
, :lisp
, :lisp-short
, :foreign
, or :foreign-static-gc
. Note that if allocation is :c
or :aligned
, it is not stack-allocated, but instead is allocated and deallocated at the appropriate places within the form.
If the type and allocation are compile-time constants, and the allocation is :foreign
, :foreign-static-gc
, :lisp
, or :lisp-short
, and the size argument is not specified, and if the body is compiled under suitable circumstances (dynamic-extent declarations are trusted), then the object is allocated on the stack. The object will disappear after control leaves body; thus the program must not maintain any pointers to the object past this point.
Otherwise, the object is allocated as specified. In this case, if the allocation requires explicit de-allocation, it is the responsibility of the application to de-allocate the object.
The size argument forces a minimum size on the allocated foreign object as in allocate-fobject. If this keyword is given, the stack allocation will fail, since this argument forces extra dynamic requirements on a construct that wants to be statically specified.
If a with-stack-fobject form is evaluated by the interpreter, or is compiled under circumstances that don't trust dynamic-extent declarations, the object will be allocated as specified (the default is as a :foreign
object). If the intent is to allocate an object that does not move during garbage collection then the allocation argument must specify a static allocation type, ie :foreign-static-gc
.
In situations where the allocation style is critical to an application, the compiled code may need to be inspected or disassembled to verify how the foreign object is allocated. A run-time check is also possible with excl::stack-allocated-p.
Multiple bindings can be done with with-stack-fobjects.
See also with-static-fobject, a macro that garantees de-allocation.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
macro, foreign-functions package
Arguments: bind-clauses &rest body
This variant of with-stack-fobject allows multiple bindings. The bind clauses are of the form
((var1 type1 [:allocation a-val1] [:size s-val1]) 2) ...
(var2 type2 [:allocation a-val2] [:size s-val] (varn typen [:allocation a-val3] [:size s-val3]))
For each clause, allocate an object of type typeN on the stack and bind it to varN while evaluating body. The object will be of allocation type specified (default :foreign
) for the purposes of accessing it with fslot-value and associated functions.
See with-stack-fobject for a detailed description of the arguments and the allocation rules.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: (var type &key allocation size) &rest body
This macro allocates a foreign object of the specified type, allocation, and size, and binds it to var while evaluating body. The body is evaluated inside a lexical binding of var. Within the body, the object may be accessed, when the allocation argument is not :aligned
, using fslot-value; and when allocation is :aligned
, with fslot-value-typed called with the allocation argument :aligned
. The default allocation is :foreign
, which for this macro only is equivalent to :foreign-static-gc
. Under the right circumstances (described below) the object may be allocated on the stack.
If the type and allocation are compile-time constants, and the allocation is :foreign
, :foreign-static-gc
, :lisp
, or :lisp-short
, and the size argument is not specified, and if the body is compiled under suitable circumstances (dynamic-extent declarations are trusted), then the object is allocated on the stack. The object will disappear after control leaves body; thus the program must not maintain any pointers to the object past this point.
Otherwise, the object is allocated as specified, and de-allocated after the body exits. Note that the de-allocation requires an implicit unwind-protect form.
The size argument forces a minimum size on the allocated foreign object as in allocate-fobject. If this keyword is given, the stack allocation will fail, since this argument forces extra dynamic requirements on a construct that wants to be statically specified.
If this form is evaluated by the interpreter, or is compiled under circumstances that don't trust dynamic-extent declarations, the object will be allocated as specified (the default is as a :foreign
object, which for this macro is equivalent to :foreign-static-gc
). Either value will allocate the object in static space so the object that does not move during garbage collection.
In situations where the allocation style is critical to an application, the compiled code may need to be inspected or disassembled to verify how the foreign object is allocated. A run-time check is also possible with excl::stack-allocated-p.
Warning: The var argument is considered dynamic-extent, and is always deallocated at the end of the form. No indefinite-extent capture of the object should be done; the object is freed regardless of whether there are any other pointers to it. Do not, for example, make the value of var be the value of a global variable for when the macro call completes, the value of the global variable may be invalid.
defvar *my-global* nil) (
Multiple bindings can be done with with-static-fobjects.
See also with-stack-fobject, a macro that does not always de-allocate the object.
See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.
Macro, foreign-functions package
Arguments: bind-clauses &rest body
This macro is a variant of with-static-fobject that allows multiple variables to be bound. The bind-clauses look like:
((var1 type1 [:allocation a-val1] [:size s-val1]) 2) ...
(var2 type2 [:allocation a-val2] [:size s-val] (varn typen [:allocation a-val3] [:size s-val3]))
For each clause, allocate an object of type typeN and bind it to varN while evaluating body. The object will be of allocation type specified (default :foreign) for the purposes of accessing it with fslot-value and associated functions.
See with-static-fobject for a detailed description of the arguments and the allocation rules.
Copyright (c) Franz Inc. Lafayette, CA., USA. All rights reserved.
|
Allegro CL version 11.0 |