Next Previous Up Top Contents Index

1.6 Defining types

define C-subtype

Definition macro

Summary

Defines a specialized designator class for a C type based on an existing designator class for that type.

Signature

define [modifiers*] C-subtype name (superclasses) 
  [slot-spec; ...] [;]
  [type-options] [;]
end [C-subtype] [name]

Arguments

modifiers
The same as the modifiers allowed in define-class.

name
A Dylan variable name.

superclasses
A list of Dylan names.

slot-spec
Same syntax as a slot definition in define-class.

type-options
A property list.

name

Values

Library

c-ffi

Module

c-ffi

Description

Defines a specialized designator class for a C type based on an existing designator class for that type. It does this by defining a subclass of the original designator class, and is a simple wrapper around define class from which it takes its syntax. The superclasses, slot-specs, and modifiers are passed on to define class unchanged. In effect, it expands to:

define class name (superclasses)
  slot-spec; ...
end class;

In terms of C, define C-subtype can be thought of as implementing a strongly typed version of typedef because a new designator class is generated that Dylan's type system can distinguish from the designator class on which it was based. As well as inheriting from an existing designator class, other Dylan classes can be mixed in too.

The optional type-options must be a property list. The c-name: keyword is recognized, allowing the original C name of the type designated by the class to be documented. The pointer-type-name: keyword option can be used to name the designator for pointers to name.

Some example C declarations:

typedef void *Handle;
typedef Handle WindowHandle;
typedef Handle StreamHandle;

extern WindowHandle CurrentWindow (void); extern StreamHandle CurrentStream (void);

Example FFI definitions:
define C-subtype <Handle> (<void*>) end;
define C-subtype <WindowHandle> (<Handle>) end;
define C-subtype <StreamHandle> (<Handle>) end;

define C-function CurrentWindow result value :: <WindowHandle>; c-name: "CurrentWindow"; end C-function;

define C-function CurrentStream result value :: <StreamHandle>; c-name: "CurrentStream"; end C-function;

Example transactions:

? <void*> == <WindowHandle> | <WindowHandle> ==
               <StreamHandle>;
#f

? define variable *cw* = CurrentWindow(); // Defined *cw*

? *cw* {<WindowHandle> #xff5400}

? define variable *cs* = CurrentStream(); // Defined *cs*

? *cs* {<StreamHandle> #xff6400}

? instance?(*cs*, <WindowHandle>) | instance?(*cw*, <StreamHandle>); #f

The following example uses the ability to specify extra superclasses to place a type beneath an abstract class.

Example C declarations:

struct _Matrix {
  int rank;
  int *dimensions;
  int *values;
};

typedef struct _Matrix *Matrix;

extern Matrix MatrixAdd (Matrix m, Matrix n);

Example FFI definitions:

define C-struct <_Matrix-struct>
  slot rank :: <C-int>;
  slot dimensions :: <C-int*>;
  slot values :: <C-int*>;
  pointer-type-name: <_Matrix-struct*>;
end C-struct;

define C-subtype <Matrix> (<_Matrix-struct*>, <number>) end;

define C-function MatrixAdd parameter m :: <Matrix>; parameter n :: <Matrix>; result value :: <Matrix>; c-name: "MatrixAdd"; end C-function;

define method \+ (m1 :: <Matrix>, m2 :: <Matrix>) => (r :: <Matrix>) MatrixAdd(m1, m2) end method;


C FFI and Win 32 Reference - 31 MAR 2000

Next Previous Up Top Contents Index