ToC DocOverview CGDoc RelNotes FAQ Index PermutedIndex
Allegro CL version 11.0

foreign-functions operators


address-to-aligned

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.


aligned-to-address

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.


allocate-fobject

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.

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.

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.


allocate-fobject-c

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.


allocate-fobject-fp

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.


bind-c-alternate

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.


bind-c-constant

Macro, foreign-functions package

Arguments: id val

This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.


bind-c-export

Macro, foreign-functions package

Arguments: id

This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.


bind-c-function

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.


bind-c-sizeof

Macro, foreign-functions package

Arguments: type

This macro is used in the Cbind facility. See cbind-intro.html for information on that facility.


bind-c-type

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.


bind-c-typedef

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.


canonical-ftype

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.


char*-string-length

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.


char*-to-euc

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.


char*-to-string

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*
                       :external-format :default)

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.


compile-foreign-type

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))))
#S(foreign-functions::iforeign-type :attributes nil
                                    :sftype
                                    #S(foreign-functions::sized-ftype-struct
                                    :kind :struct
                                    :width 8
                                    :offset 0
                                    :pad 0
                                    :align 4
                                    :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.


convert-foreign-name

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.


convert-to-lang

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.


def-c-type

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 integers 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.


def-c-typedef

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.


def-foreign-call

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 and (:void) have special meanings.

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 nil unless strings-convert is specified nil. See Note 4: String conversion when no arguments are specified after the table.

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 :foreign-address is specified. The :aligned type passes a Lisp fixnum as if it were a machine integer (resulting in a value with the lowest 3 (64-bit) or 2 (32-bit) bits 0). This can serve as a pointer aligned on an 8 byte (64-bit) or 4 byte (32-bit) boundary and it avoids potential bignum calculations. See Aligned Pointers and the :aligned type in ftype.html for more information on :aligned.

returning Keyword argument.

Default: the foreign type :int, with a conversion to Lisp type integer (a fixnum with a possible overflow to a bignum). See Note 7: Potential problems with foreign functions returning :int in 64-bit Lisps for possible problems with returning :int on 64-bit Lisps.

The value can also be:

A foreign type (defined by def-foreign-type

A list of a foreign type and a Lisp type. Example: (:double single-float). See also Note 8: Returning booleans.

A list of a foreign type, a Lisp type, and a symbol naming a user-defined conversion function. Example: (:double single-float my-conversion-function). See section The user-conversion function in a complex-type-spec in foreign-functions.html for more information on this option.

((* :char)), or ((* :char) string), etc. Causes native-to-string to be called automatically after the return. The alternative specification of defining the returning value as an integer and then to explicitly call with-native-string on the result, still works, and should be used if any external-format other than :default is desired.

:lisp, meaning a Lisp object. No conversion is done. If not actually a Lisp object, gc failure is possible. See Note 9 on the :lisp return type below for more information on this choice.

:foreign-address (an integer which will be converted to a Lisp integer (fixnum or bugnum). The :aligned return type will return an address aligned on an 8 (64-bit) or 4 (32-bit) byte boundary (meaning the lowest 3 or 2 bits are 0) which will look to Lisp like a fixnum. See Aligned Pointers and the :aligned types in ftype.html for more information. The (:aligned ftype) specification is not supported.

:single-float-from-double, a double is returned and it is converted to a single. This specification is deprecated though it will work. The preferred specification is (:double single-float)

:void, nothing is returned, the Lisp function returns nil (:void is actually a foreign type).

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

:returning (:int fixnum)

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 :foreign-address is specified, the return value will be interpreted as an unsigned integer and converted to a positive Lisp integer. The system will not store this value into a foreign-pointer object. The discussion in A note on foreign addresses in foreign-functions.html does not specifically apply to returning values. Programmers can add code to store the returned value as desired.

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 (ff:def-foreign-call foo ()) would result in an entry-point structure that adheres to whatever library is last loaded. So if one calls foo before either library is loaded in, an error will result noting that the entry's library is not yet or no longer loaded. If one then loads liba.so, calling foo will call the "foo" function in liba.so, and if one then loads libb.so then calling foo will result in calling the "foo" function in libb.so. This dynamicity is a useful way to swap out implementations with similar interfaces, in the spirit of lisp dynamicity.

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 :libname option allows this to happen:

(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 :libname option so that it is likely only to be included in one library.

Note that on the FreeBSD platform, there is no way to determine accurately where the symbol is loaded. Thus, on a freebsd system, the :libname argument is effectively ignored.

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 (addr :int) is converted to (addr :int (integer -2147483648 2147483647)) so the argument checking mechanism will produce an error if the argument is anywhere outside of the range of a signed 32-bit integer.

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-nil, the call cannot be a direct-call so call-direct is ignored (but a warning is printed if call-direct is non-nil).

method-index [Windows Only] 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-nil value for this argument.

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 nil (meaning that no information about the type or the number of arguments is supplied) and this argument is unspecified, string conversion is enabled and a warning is printed stating that fact. See Note 4: String conversion when no arguments are specified after the table.

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.

:errno gets the most recent value of the errno variable and returns it as the second return value from the foreign call.

:os-specific gets an architecture/operating-system specific error value and returns it as the second return value from the foreign call. On Windows systems, the GetLastError() function is used to get this error value. Currently, all other architectures retrieve the value of the errno variable.

call-direct is ineffective if error-value is non-nil (a warning is printed and the call-direct argument is ignored if non-nil values are specified for both error-value and call-direct).

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.

Note 1: Argument specifications

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:

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:

Here is an example:

  (a (b :int fixnum) (c :lisp))

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.

Note 2: Possible values for convention

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 convention on Windows does not work

: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.

Note 3: the release-heap keyword argument

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:

Garbage collections in an SMP Lisp

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.

Note 4: String conversion when no arguments are specified

(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.

Note 5: More on the error-value 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 two acceptable non-nil values for error-value are :errno and :os-specific.

On UNIX and UNIX-like platforms

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.

On Windows

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().

Note 6: More on the method-index argument

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.

Note 7: Potential problems with foreign functions returning :int in 64-bit Lisps

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.

Note 8: Returning booleans

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).

Note 9 on the :lisp return type

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.

Note 10: Character signedness

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.

Examples:

(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)
                            (y :double single-float)
                            (z :int fixnum))
  :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))
                                                (z :int fixnum)
                                                (w (* :char) string))
  :returning #-(or (and sun4 (not svr4)) sun3q) :float
             #+(or (and sun4 (not svr4)) sun3q) (:double single-float)

(def-foreign-call (t-float "t_float") ((x :double)
                                                (y (:float :no-proto))
                                                (z :int fixnum)
                                                (w (* :char) string))
  :returning #-(or (and sun4 (not svr4)) sun3q) :float
             #+(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.

Macroexpansion of a def-foreign-call-form now provides more useful information

def-foreign-call has enhanced the macroexpansion to give useful information for users. Here is an example:

cl-user(11): (pprint 
               (macroexpand '(ff:def-foreign-call foo (x (y (* :char))))))

Warning: A runtime with-native-string call is being generated for argument `y'
         to the foreign-function `foo'.  The with-native-string macro can be
         used for explicit string conversions around the foreign calls.  This
         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 'function
           'foreign-functions:def-foreign-call (fboundp 'foo))
         (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 foo
                      (lambda (x y)
                        (excl::check-ff-args '((:int
                                                (integer
                                                 -2147483648
                                                 2147483647))
                                               ((* :char)
                                                (array character (*))))
                                             'foo nil x y)
                        (with-native-string (#:g158
                                             (if*
                                              (stringp y)
                                              then y
                                              else ""))
                          (unless (stringp y) (setq #:g158 y))
                          (symbol-macrolet ((y #:g158))
                            (system::ff_funcall (load-time-value
                                                 (excl::determine-foreign-address-1
                                                  '("foo" :language :c)
                                                  2
                                                  nil
                                                  nil
                                                  16))
                                                '(:int
                                                  (integer
                                                   -2147483648
                                                   2147483647))
                                                x
                                                '((* :char)
                                                  (array
                                                   character
                                                   (*)))
                                                y
                                                '(:int
                                                  (integer
                                                   -2147483648
                                                   2147483647)))))))))
               (excl::set-func_name excl::f 'foo)
               excl::f))
       (excl::put-property 'foo nil 'excl::%fun-documentation)
       (record-source-file 'foo) 'foo)
cl-user(12): 

The effects of the new, longer array implementation on def-foreign-call

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.


def-foreign-constant

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.

Accessibility and caching

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.


def-foreign-type

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:

   (def-foreign-type one (:struct (nil :int)))
   (def-foreign-type two one)
   (def-foreign-type one (:struct (nil (:array :int 4))))

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

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:

(def-foreign-type (foostruct (:pack 1)) (:struct (x :char) (y :int)))

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:

(def-foreign-type (barstruct (:pack 2))
  (: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.

The :superclass attribute

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.

Compatibility note:

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:

cl-user(5): (setq p (allocate-fobject 'my-point))
#<foreign object of class my-point>
cl-user(6): (type-of p)
(short-simple-array foreign (3))
cl-user(7): (class-of p)
#<foreign-functions::foreign-structure my-point>
cl-user(8):

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:

cl-user(5): (setq p (allocate-fobject 'my-point))
#<foreign object of class my-point>
cl-user(6): (type-of p)
my-point
cl-user(7): (class-of p)
#<foreign-functions::foreign-structure my-point>
cl-user(8): (typep p 'my-point)
t
cl-user(9): (typep p 'my-rect)
nil
cl-user(10): (setq r (allocate-fobject 'my-rect))
#<foreign object of class my-rect>
cl-user(11): (typep r 'my-rect)
t
cl-user(12): (typep r 'my-point)
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.


def-foreign-variable

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.


defcstruct

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.

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.


defforeign

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 :lisp is also accepted as an argument-type. Arguments specified :lisp are passed to foreign code unconverted. The format of Lisp objects is given in the sys:;misc;lisp.h file. Please be aware that if a Lisp object is modified inappropriately by foreign code, Lisp will likely fail unrecoverably. Also note that the Lisp object may be moved by the garbage collector so the reference may not be valid if it is stored by C for later processing.

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 nil. If proto is t, then all arguments will be prototyped. If the arguments are only partially prototyped (e.g. only the first few are prototyped), then the value of the prototype argument should be a list containing t's in the prototyped positions.

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 t or nil as the foreign code returned a non-zero or 0 value.

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.
print 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 :long-long and :unsigned-long-long (which are 64-bit values) are not supported for :call-direct foreign calls on 32- or 64-bit Windows or in 32-bit Lisps. (In other 64-bit Lisps, they are okay because they are the same as :long and :unsigned-long).

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.


defforeign-list

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.


defun-c-callable

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.


defun-foreign-callable

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.

The :lisp argument type: signals a warning

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:

cl-user(3): (ff:defun-foreign-callable foo ((x :double) (y :lisp)))
Warning: While defining foo: for foreign callback-arg named y,
         specifying :lisp as a foreign type for a transition from
         foreign to lisp space is dangerous because the object may move
         due to an intervening garbage collection. If the object is an
         aligned address consider instead using the :aligned
         specification.  Otherwise, if the object is static or if
         careful analysis shows that no movement can possibly occur,
         then add the :lisp-args-will-not-move option in the definition
         in order to remove this warning.
foo
cl-user(4): (ff:defun-foreign-callable foo ((x :double) (y :lisp)) 
                (declare (:lisp-args-will-not-move t)))
foo
cl-user(5):

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 body argument and its declaration

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:

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.

Using a function defined by defun-foreign-callable

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.

Strings passed as arguments

Consider this call to defun-foreign-callable:

(defun-foreign-callable gdbm-error-handler ((string (* :char)))
  (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 and tracing foreign-callable functions

Fwrapping (see fwrappers-and-advice.html) and thus tracing (see The tracer in debugging.html will now work on foreign-callable functions.

For more information on foreign 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.


describe-fobject

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.


ensure-foreign-type

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.


euc-to-char*

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.


fobjectp

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.


foreign-address

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.


foreign-address-p

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.


foreign-pointer-address

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.


foreign-pointer-p

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.


foreign-pointer-type

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.


foreign-strlen

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).


foreign-type-lisp-pre-padding

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.


foreign-type-p

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.


free-cstruct

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.


free-fobject

function, foreign-functions package

Arguments: fobj

Free an object that was allocated by allocate-fobject with the allocation of :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.


free-fobject-aligned

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.


free-fobject-c

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.


free-fobject-fp

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.


fslot-address

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-gcobjects. 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.


fslot-address-c

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.


fslot-address-fp

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.


fslot-address-type

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.


fslot-address-typed

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.


fslot-value

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.


fslot-value-c

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.


fslot-value-fp

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.


fslot-value-typed

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:

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.

Examples

;;  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)
       (nums (:array :int 17))
       (floats (:array :float 11 12))
       (internal sub-rec)
       (pointer (* record-date))
       (sarray (:array sub-rec 7))
       ))

(setq x (allocate-fobject 'record))

(setq rd (allocate-fobject 'record-date :c))

(fslot-value-typed 'record nil x 'num1)
RETURNS the integer value of slot num1

(fslot-value-typed 'record nil x 'nums 3)
RETURNS the integer value of element 3 of 
the array at slot nums

(fslot-value-typed 'record nil x 'floats 5 7)
RETURNS the float indexed with 5 and 7 in 
the array at slot floats

(fslot-value-typed 'record nil x 'internal)
RETURNS an integer that represents the 
address of the sub-structure.

(fslot-value-typed 'record nil x 'internal 'a)
RETURNS the integer value of slot a of 
the sub-structure of type sub-rec at slot internal

(fslot-value-typed 'record nil x 'pointer)
RETURNS the address in slot pointer
This address is an integer that can be used with the
allocation type :c to access data stored at 
the pointer location

(setf (fslot-value-typed 'record nil x 'pointer) rd)

(fslot-value-typed 'record nil x 'pointer '* 'year)
RETURNS the integer value of slot year in the instance
of type record-date stored at the address in slot pointer

(fslot-value-typed 'record nil x 'sarray 3 'b)
RETURNS the integer value of slot b in the structure of
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-pointer '(* (:array (* PangoFontFamily))))
       (count-integer '(:array gint 1)))
    (pango_context_list_families
     (or pango-context (gdk_pango_context_get))
     array-pointer count-integer)
    (do* ((faces nil)
      (count (fslot-value-typed '(:array gint 1) nil
                    count-integer 0))
      (j 0 (1+ j)))
    ((>= j count)
     (sort faces #'string<))
      (push (native-to-string
         (pango_font_family_get_name
          (fslot-value-typed '(* (:array (* PangoFontFamily)))
                 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.


get-entry-point

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).

cl-user(101): (ff:get-entry-point "aclmalloc")
1872778976
4
cl-user(102): (get-shared-library-handle)
4
cl-user(103): (get-shared-library-name)
"libacli61pf4.so"
cl-user(104): 

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.


get-entry-points

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.


get-extern-code-address

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.


get-extern-data-address

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.


get-foreign-type

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.


lisp-value

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.


list-all-foreign-libraries

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.


make-cstruct

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.


make-foreign-pointer

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.

The aligned argument

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.

The address and type arguments

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.


malloc-cstruct

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.


register-foreign-callable

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.


register-function

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.


register-lisp-value

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.


register-value

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.


remove-entry-point

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.


remove-extern-code-address

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.


remove-extern-data-address

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.


sizeof-fobject

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.

Example

cl-user(1): (ff:def-foreign-type point (:struct (x :int) (y :int)))
#<foreign-functions::foreign-structure point>
cl-user(2): (setq obj (ff:allocate-fobject 'point :foreign-static-gc))
#<foreign object of class point>
cl-user(3): (ff:sizeof-fobject 'point)
8
cl-user(4): (ff:sizeof-fobject (ff:get-foreign-type 'point))
8
cl-user(5): (ff:sizeof-fobject obj)
8
cl-user(6): 

See ftype.html for information on foreign types in Allegro CL and foreign-functions.html for general information on foreign functions in Allegro CL.


string-to-char*

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* 
                       :external-format :default)

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.


string-to-wchar*

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:

(excl:string-to-native string 
    :address <em>address</em> :external-format :16-bit)

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.


unload-foreign-library

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.


unregister-foreign-callable

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.


unregister-function

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.


unregister-lisp-value

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.


unregister-value

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.


wchar*-string-length

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.


wchar*-to-string

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.


with-stack-fobject

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.


with-stack-fobjects

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]) 
 (var2 type2 [:allocation a-val2] [:size s-val]2) ... 
 (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.


with-static-fobject

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.


with-static-fobjects

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]) 
 (var2 type2 [:allocation a-val2] [:size s-val]2) ... 
 (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) 2023, Franz Inc. Lafayette, CA., USA. All rights reserved.

ToC DocOverview CGDoc RelNotes FAQ Index PermutedIndex
Allegro CL version 11.0