Definition macro
Allows you to define a name to which to bind a pointer designator.
define modifiers C-mapped-subtype type-name (superclasses)
[map high-level-type [, import-function: import-fun]
[, export-function: export-fun];]
[import-map high-level-type,
import-function: import-function;]
[export-map high-level-type,
export-function: export-function;]
[type-options]
end
define-class.
<function>.
<function>.
<function>.
type-options c-ffi
c-ffi
Allows you to define a name to which to bind a pointer designator.
The modifiers may be sealed or open. (The default is sealed.) Their effect on the class defined is the same as the similar modifiers on an ordinary class.
The possible combinations are, a map clause, an import-map clause, an export-map clause, or both an import-map and an export-map clause. Any other combinations are illegal.
The import-map clause specifies that a type conversion takes place when type-name is used as a designator for values imported from C into Dylan. The conversion is accomplished by calling the import-function on the imported value. This call is automatically inserted into function wrappers, structure member getters, pointer-value dereference functions and so on by the C-FFI. The high-level-type is used as the Dylan type specifier for the appropriate parameter or result in any wrapper function or c-struct accessor which uses the defined class. The export-map clause specifies a similar type conversion for exported values. The high-level-type must in either case name an instantiable Dylan type.
map <type-c>;
is equivalent to:
import-map <type-c>; export-map <type-c>;
The import and export functions are monadic functions whose single argument is the appropriate low-level value for export functions and the appropriate Dylan type for import functions. Any mapped subtype which specifies an import-map must specify an import-function. Any mapped subtype which specifies an export-map must specify an export-function.
Map boolean example:
bool-header.h:
typedef int bool;
bool bool_function (bool b);
void bool_pointer_function (bool *b);
//eof
Module: my-module
define C-mapped-subtype <bool> (<C-int>)
map <boolean>,
export-function:
method (v :: <boolean>) => (result :: <integer>)
as(<integer>, if(v) 1 else 0 end if) end,
import-function:
method (v :: <integer>) => (result :: <boolean>)
~zero?(v) end;
end;
//end module
Mapped string example: an alternate version of C-string which automatically converts instances of <byte-string> to instances of <C-example-string> on export.
string-header.h typedef char *string; string string-filter(string s); void string-modifier(string *s); //eof module: my-module define C-mapped-subtype <C-example-string> (<C-char*>, <string>) export-map type-union(<byte-string>, <C-example-string>), export-function: c-string-exporter; end; define method c-string-exporter (s :: <byte-string>) => (result :: <C-char*>) as(<C-example-string>, s) end; define method c-string-exporter (s :: <C-example-string>) => (result :: <C-example-string>) s end; //end module
It is possible to define an ordinary subtype of a mapped supertype. The mapping characteristic of the subtype is inherited from the supertype. It is also possible to define a mapped subtype of a mapped supertype. When the subtype and supertype both specify an export function, the export functions of the subtype and the supertype are composed with the subtype's export function applied to the result of the supertype's export function. Import functions of a mapped subtype and supertype are similarly composed. Mapping characteristics are inherited from the supertype where the subtype does not define them. (You can think of this as composition with identity when either the supertype or subtype fails to specify an import or export function.) This shadowing is only useful when import and export maps are defined separately. Here is an example of a mapped subtypes which adds an import map to the mapped version of <C-example-string> defined above.
define C-mapped-subtype <other-string>
(<C-example-string>)
import-map <byte-string>,
import-function: method (v :: <byte-string>) =>
(result :: <C-example-string>)
as(<C-example-string>, v)
end method;
end;
The import signature is <byte-string>. The export signature is inherited from <C-example-string> type-union(<byte-string>, <C-example-string>). For a example involving composition of mapped types consider the following (hypothetical) definitions of <C-raw-int>, <C-mapped-int> and <bool>. The <C-raw-int> class is a primitive which returns and accepts instances of <machine-word>. The <C-mapped-int> class is a mapped subtype which converts the instances of <machine-word> to instances of <integer>. The <bool> class is a mapped subtype of <C-mapped-int> which converts to and from <boolean>.
define C-mapped-subtype <C-mapped-int> (<C-raw-int>)
map <boolean>,
export-function:
method (v :: <integer>) =>
(result :: <machine-word>)
as(<machine-word>, v) end,
import-function:
method (v :: <machine-word>) =>
(result :: <integer>)
as(<integer>, v) end;
end;
define C-mapped-subtype <bool> (<C-mapped-int>)
map <boolean>,
export-function:
method (v :: <boolean>) => (result :: <integer>)
if(v) 1 else 0 end if) end,
import-function:
method (v :: <integer>) => (result :: <boolean>)
~zero?(v) end;
end;