| Allegro CL version 10.0 Unrevised from 9.0 to 10.0. 9.0 version |
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.htm.)
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 implementation.htm.)
|
:c |
A Lisp integer representing the address of the object in memory. |
:aligned |
A Lisp integer representing the aligned address of the object in memory. |
nil |
Any of the four types above. |
The slot-names are symbols or integers. Symbols name the slots to access. Integers are used to specify array indices.
The symbol naming a slot can either be the exact symbol used when the type was defined, or it can be a keyword package symbol with the same symbol-name as the one used to define the slot.
When the accessed slot is a primitive type, then the value of the slot is returned. When the accessed slot is a composite type such as a sub-structure or an array, then the address of the sub-structure or array is returned as a Lisp integer. Please see the caution in the description of fslot-address-typed about using the returned address value.
The special slot-name asterisk * is used to denote dereferencing a pointer. If a slot has the type (* foo) then you use the * slot name to indicate that you want to follow the pointer to the foo-typed object. If the object is an array, then the asterisk will access the first element of the array (the element at index zero).
When the allocation argument is
not nil
, and the slot names are all
constants, then this function will be open coded by the compiler if
the optimize-fslot-value-switch
is true.
setf can be used with this function to change the value.
;; Here are some general examples. We create foreign types and ;; allocate some instances (we do not specify any values, so ;; the values you see if you do this are defaults or meaningless ;; data. (def-foreign-type sub-rec (:struct (a :int) (b :int))) (def-foreign-type record-date (:struct (day :int) (month :int) (year :int))) (def-foreign-type record (:struct (num1 :int) (num2 :int) (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 Types in
ftype.htm 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.
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.htm for information on foreign types in Allegro CL and foreign-functions.htm for general information on foreign functions in Allegro CL.
Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 9.0 page.
Created 2015.5.21.
| Allegro CL version 10.0 Unrevised from 9.0 to 10.0. 9.0 version |