source: project/chicken/trunk/manual/Accessing external objects @ 5945

Last change on this file since 5945 was 5945, checked in by felix winkelmann, 12 years ago

renamed some tools in misc/; apply hack fix on x86-64 (again); re-added manual

File size: 10.9 KB
Line 
1[[tags: manual]]
2
3[[toc:]]
4
5== Accessing external objects
6
7=== foreign-code
8
9 [syntax] (foreign-code STRING ...)
10
11Executes the embedded C/C++ code {{STRING ...}}, which should
12be a sequence of C statements, which are executed and return an unspecified result.
13
14<enscript highlight=scheme>
15(foreign-code "doSomeInitStuff();")     =>  #<unspecified>
16</enscript>
17
18Code wrapped inside {{foreign-code}} may not invoke callbacks into Scheme.
19
20
21=== foreign-value
22
23 [syntax] (foreign-value STRING TYPE)
24
25Evaluates the embedded C/C++ expression {{STRING}}, returning a value of type given
26in the foreign-type specifier {{TYPE}}.
27
28<enscript highlight=scheme>
29(print (foreign-value "my_version_string" c-string))
30</enscript>
31
32
33=== foreign-declare
34
35 [syntax] (foreign-declare STRING ...)
36
37Include given strings verbatim into header of generated file.
38
39
40=== define-foreign-type
41
42 [syntax] (define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])
43
44Defines an alias for {{TYPE}} with the name {{NAME}} (a symbol).
45{{TYPE}} may be a type-specifier or a string naming a C type. The
46namespace of foreign type specifiers is separate from the normal
47Scheme namespace.  The optional arguments {{ARGCONVERT}} and
48{{RETCONVERT}} should evaluate to procedures that map argument- and
49result-values to a value that can be transformed to {{TYPE}}:
50
51<enscript highlight=scheme>
52(define-foreign-type char-vector
53  nonnull-c-string
54  (compose list->string vector->list)
55  (compose list->vector string->list) )
56
57(define strlen
58  (foreign-lambda int "strlen" char-vector) )
59
60(strlen '#(#\a #\b #\c))                      ==> 3
61
62(define memset
63  (foreign-lambda char-vector "memset" char-vector char int) )
64
65(memset '#(#_ #_ #_) #\X 3)                ==> #(#\X #\X #\X)
66</enscript>
67
68Foreign type-definitions are only visible in the compilation-unit in which
69they are defined, so use {{include}} to use the same definitions
70in multiple files.
71
72
73=== define-foreign-variable
74
75 [syntax] (define-foreign-variable NAME TYPE [STRING])
76
77Defines a foreign variable of name {{NAME}} (a symbol). {{STRING}}
78should be the real name of a foreign variable or parameterless
79macro. If {{STRING}} is not given, then the variable name {{NAME}}
80will be converted to a string and used instead. All references and
81assignments (via {{set!}}) are modified to correctly convert values
82between Scheme and C representation. This foreign variable can only be
83accessed in the current compilation unit, but the name can be
84lexically shadowed.  Note that {{STRING}} can name an arbitrary C
85expression. If no assignments are performed, then {{STRING}} doesn't
86even have to specify an lvalue.
87
88<enscript highlight=scheme>
89#>
90enum { abc=3, def, ghi };
91<#
92
93(define-macro (define-simple-foreign-enum . items)
94  `(begin
95     ,@(map (match-lambda
96              [(name realname) `(define-foreign-variable ,name int ,realname)]
97              [name `(define-foreign-variable ,name int)] )
98     items) ) )
99
100(define-simple-foreign-enum abc def ghi)
101
102ghi                               ==> 5
103</enscript>
104
105
106=== define-foreign-record
107
108 [syntax] (define-foreign-record NAME [DECL ...] SLOT ...)
109
110Defines accessor procedures for a C structure definition. {{NAME}} should either be a symbol
111or a list of the form {{(TYPENAME FOREIGNNAME)}}. If {{NAME}} is a symbol, then a C declaration
112will be generated that defines a C struct named {{struct NAME}}. If {{NAME}} is a list, then
113no struct declaration will be generated and {{FOREIGNNAME}} should name an existing C record type.
114A foreign-type specifier named {{NAME}} (or {{TYPENAME}}) will be defined as a pointer to
115the given C structure.
116A {{SLOT}} definition should be a list of one of the following forms:
117
118 (TYPE SLOTNAME)
119
120or
121
122 (TYPE SLOTNAME SIZE)
123
124The latter form defines an array of {{SIZE}} elements of the type {{TYPE}} embedded in the
125structure.
126For every slot, the following accessor procedures will be generated:
127
128
129==== TYPENAME-SLOTNAME
130
131 (TYPENAME-SLOTNAME FOREIGN-RECORD-POINTER [INDEX])
132
133A procedure of one argument (a pointer to a C structure), that returns
134the slot value of the slot {{SLOTNAME}}. If a {{SIZE}} has been given in the slot definition, then
135an additional argument {{INDEX}} is required that specifies the index of an array-element.
136
137
138==== TYPENAME-SLOTNAME-set!
139 
140 (TYPENAME-SLOTNAME-set! FOREIGN-RECORD-POINTER [INXDEX] VALUE)
141
142A procedure of two arguments (a pointer to a C structure) and a value, that
143sets the slot value of the slot {{SLOTNAME}} in the structure. If a {{SIZE}} has been given in
144the slot definition, then an additional argument {{INDEX}} is required for the array index.
145
146
147If a slot type is of the form {{(const ...)}}, then no setter procedure will be generated.
148Slots of the types {{(struct ...)}} or {{(union ...)}} are accessed as pointers to the embedded
149struct (or union) and no setter will be generated.
150
151Additionally, special record-declarations ({{DECL ...}}) may be given, where each declaration consists
152of a list of the form {{(KEYWORD ARGUMENT ...)}}. The available declarations are:
153
154==== constructor
155
156 (constructor: NAME)
157
158Generate a constructor-procedure with no arguments that has the name {{NAME}} (a symbol) that returns a pointer to a structure of this
159type. The storage will be allocated with {{malloc(3)}}.
160
161
162==== destructor
163
164 (destructor: NAME)
165
166Generate a destructor function with the name {{NAME}} that takes a pointer to a structure of this
167type as its single argument and releases the storage with {{free(3)}}. If the argument is {{#f}},
168the destructor procedure does nothing.
169
170
171==== rename
172
173 (rename: EXPRESSION)
174
175Evaluates {{EXPRESSION}} at compile-/macro-expansion-time and applies the result, which should be
176a procedure, to the string-representation of the name of each accessor-procedure generated. Another (or the same)
177string should be returned, which in turn is taken as the actual name of the accessor.
178
179
180An example:
181
182<enscript highlight=scheme>
183(require-for-syntax 'srfi-13)
184
185(define-foreign-record Some_Struct
186  (rename: (compose string-downcase (cut string-translate <> "_" "-")))
187  (constructor: make-some-struct)
188  (destructor: free-some-struct)
189  (int xCoord)
190  (int yCoord) )
191</enscript>
192
193will generate the following procedures:
194
195<enscript highlight=scheme>
196(make-some-struct)              --> C-POINTER
197(free-some-struct C-POINTER)
198
199(some-struct-xcoord C-POINTER)  --> NUMBER
200(some-struct-ycoord C-POINTER)  --> NUMBER
201
202(some-struct-xcoord-set! C-POINTER NUMBER)
203(some-struct-ycoord-set! C-POINTER NUMBER)
204</enscript>
205=== define-foreign-enum
206
207 [syntax] (define-foreign-enum TYPENAME ITEM ...)
208
209Defines a foreign type (as with {{define-foreign-type}}) that maps the elements
210of a C/C++ enum (or a enum-like list of constants) to and from a set of
211symbols.
212
213{{TYPENAME}} specifies a foreign type that converts a symbol argument from the
214set {{ITEM ...}} into the appropriate enum value when passed as an argument to
215a foreign function.
216
217A list of symbols passed as an argument will be combined using {{bitwise-ior}}.
218An empty list will be passed as 0 (zero). Results of the enum type are
219automatically converted into a scheme value (note that combinations are not
220supported in this case).
221
222{{TYPENAME}} maybe a symbol or a list of the form {{(SCHEMENAME REALTYPE
223[DEFAULT-SCHEME-VALUE])}}, where {{REALTYPE}} designates the native type used.
224The default native type is {{"TYPENAME"}}. The {{DEFAULT-SCHEME-VALUE}}
225overrides the default result of mapping from the native type; i.e. when no such
226mapping exists. When supplied the form is used unquoted, otherwise the result
227is {{'()}}.
228
229{{ITEM}} is a symbol or a list of the form {{(SCHEMENAME REALTYPE
230[SCHEME-VALUE])}}, where {{REALTYPE}} designates the native type used. The
231default native type is {{"ITEM"}}. The {{SCHEME-VALUE}} overrides the result of
232mapping from the native type. When supplied the form is used unquoted,
233otherwise the {{SCHEMENAME}} symbol is returned.
234
235Additionally two procedures are defined named {{SCHEMENAME->number}} and
236{{number->SCHEMENAME}}. {{SCHEMENAME->number}} takes one argument and converts
237a symbol (or a list of symbols) into its numeric value.  {{number->SCHEMENAME}}
238takes one argument and converts a numeric value into its scheme value.
239
240Note that the specification of a scheme value override means the mapping may
241not be closed! {{(number->SCHEMENAME (SCHEMENAME->number SCHEMENAME))}} may not
242equal {{SCHEMENAME}}.
243
244Here a heavily contrived example:
245
246<enscript highlight=scheme>
247#>
248enum foo { a_foo = 4, b_foo, c_foo };
249enum foo bar(enum foo x) { printf("%d\n", x); return b_foo; }
250<#
251
252(define-foreign-enum (foo (enum "foo")) a_foo b_foo (c c_foo))
253
254(define bar (foreign-lambda foo bar foo))
255
256(pp (bar '()))
257(pp (bar 'a_foo))
258(pp (bar '(b_foo c)))
259</enscript>
260
261
262=== foreign-lambda
263
264 [syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...)
265
266Represents a
267binding to an external routine. This form can be used in the position
268of an ordinary {{lambda}} expression. {{NAME}} specifies the
269name of the external procedure and should be a string or a symbol.
270
271
272=== foreign-lambda*
273
274 [syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
275
276Similar to {{foreign-lambda}}, but instead of generating code to
277call an external function, the body of the C procedure is directly given
278in {{STRING ...}}:
279
280<enscript highlight=scheme>
281(define my-strlen
282  (foreign-lambda* int ((c-string str))
283    "int n = 0;
284     while(*(str++)) ++n;
285     C_return(n);") )
286
287(my-strlen "one two three")             ==> 13
288</enscript>
289
290For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement
291to return a result from the foreign lambda body as some cleanup code has to be run before execution
292commences in the calling code.
293
294=== foreign-safe-lambda
295
296 [syntax] (foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)
297
298This is similar to {{foreign-lambda}}, but also allows the called
299function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
300
301
302=== foreign-safe-lambda*
303
304 [syntax] (foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)
305
306This is similar to {{foreign-lambda*}}, but also allows the called
307function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
308
309
310
311=== foreign-primitive
312
313 [syntax] (foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)
314
315This is also similar to {{foreign-lambda*}} but the code will be executed
316in a ''primitive'' CPS context, which means it will not actually return, but
317call it's continuation on exit. This means that code inside this form may
318allocate Scheme data on the C stack (the ''nursery'') with {{C_alloc}}
319(see below). If the {{RETURNTYPE}} is omitted it defaults to {{void}}.
320You can return multiple values inside the body of the {{foreign-primitive}}
321form by calling this C function:
322
323<enscript highlight=scheme>
324C_values(N + 2, C_SCHEME_UNDEFINED, C_k, X1, ...)
325</enscript>
326
327where {{N}} is the number of values to be returned, and {{X1, ...}} are the
328results, which should be Scheme data objects. When returning multiple values, the
329return-type should be omitted.
330
331
332Previous: [[Interface to external functions and variables]]
333
334Next: [[Foreign type specifiers]]
Note: See TracBrowser for help on using the repository browser.