Definition macro
Describes C's aggregate structures.
define C-struct name [slot-spec; ...] [;] [type-options] [;] end [C-struct] [name]
c-ffi
c-ffi
Describes C's aggregate structures. The name is defined to be a designator class encapsulating the value of a structure, not a pointer to the structure. This is significant because many of the protocols associated with structures work only on pointers to structures -- pointers to structures being the most common form and the form closest to Dylan's object model. The new designator class is defined to be a subclass of <C-struct>.
Once defined, a structure-designating class is most likely to be used as the basis for a pointer type definition in terms of which most further transactions will take place. Structure-designating classes are abstract and cannot have direct instances. Accessor methods defined for the slots of the structure are specialized on the structure designator's pointer-type. However, the class itself may be needed to specify an in-line structure in another structure, union, or array, or a value-passed structure argument or result in a C function.
A slot-spec has the following syntax:
[slot-adjective] slot getter-name :: c-type #key setter address-getter c-name length width
The slot-adjective can be either array or bitfield. The array slot adjective indicates that the slot is repeated and the dimensions option is used to indicate how many repetitions are defined, and how it is accessed. The bitfield slot adjective indicates that the slot is really a bitfield. If bitfield is given then the width option must also be given. The c-type given for a bitfield slot must be an integer designator. The c-type for a bitfield slot indicates how the value is interpreted in Dylan by the slot accessor. A slot may not be specified as both an array and a bitfield.
The getter-name keyword specifies the name of the Dylan function to which the getter method for the structure slot will be added. The specializer of the getter method's single argument will be a designator indicating a pointer to the struct's name.
The c-type specifies the field's C type, and must be a designator class. Unlike Dylan slot specifications, the type declaration here is not optional.
The optional setter keyword specifies the generic function to which the setter method for the structure slot will be added. It defaults to getter-name-setter. No setter method is defined if the setter option is #f.
The optional address-getter specifies the name of a function that can be used to return a pointer to the data in the member. It must return a <C-pointer> object that points to a C type. No address-getter is defined by default.
You can use the dimensions keyword only if you used the array slot adjective. This dimensions value can be either a list of integers or a single integer. The accessor for an array slot is defined to take an extra integer parameter for each dimension given.
You can use the width keyword option only if you used the bitfield adjective.
The optional c-name keyword allows you to document the original C name of the slot.
The type-options clause is a property list allowing you to specify properties of the type as a whole. It accepts the optional keyword c-name:, allowing you to document the original C name of the struct to be documented. The optional keyword pointer-type-name: is also accepted. When given, the name is bound to the struct pointer type on which the accessors are defined.
The type option pack: n indicates that the struct has the packing semantics of Microsoft's #pragma pack(n).
Example C declaration:
struct Point {
unsigned short x;
unsigned short y;
};
Point *OnePoint(); /* Returns a pointer to a Point */
Point *PointArray(); /* Returns a Point array */
define C-struct <Point> slot x :: <C-unsigned-short>; slot y :: <C-unsigned-short>; pointer-type-name: <Point*>; end C-struct; define C-function one-point result point :: <Point*>; c-name: "OnePoint"; end C-function; define C-function point-array result array :: <Point*>; c-name: "PointArray"; end C-function;
? define variable p = one-point();
// Defined p.
? values(p.x, p.y);
100
50
? define variable array = point-array();
// Defined array.
? array[5].object-class; // implicit conversion to
// the pointer type
{<Point> pointer #xff5e00}
? begin array[5].x := 10; array[5].y := 20 end;
20
? values(array[5].x, array[5].y)
10
20