| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version |
Arguments: name definition
Defines name to be a user-defined foreign class with the given definition. 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.htm.
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
.
Only one attribute can be specified. It is:
Attribute | Type | What |
:pack | integer | worst case alignment needed by data objects. |
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.
See ftype.htm for information on foreign types in Allegro CL and foreign-functions.htm 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.
Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 8.2 page.
Created 2012.5.30.
| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version |