source: project/chicken/branches/prerelease/manual/Accessing external objects @ 9424

Last change on this file since 9424 was 9424, checked in by Ivan Raikov, 12 years ago

Merged with trunk

File size: 11.2 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 [INDEX] 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
206
207=== define-foreign-enum
208
209 [syntax] (define-foreign-enum TYPESPEC [USE-ALIASES] ENUMSPEC ...)
210
211Defines a foreign type (as with {{define-foreign-type}}) that maps the elements
212of a C/C++ enum (or a enum-like list of constants) to and from a set of
213symbols.
214
215{{TYPESPEC}} specifies a foreign type that converts a symbol argument from the
216set {{ENUMSPEC ...}} into the appropriate enum value when passed as an argument to
217a foreign function.
218
219A list of symbols passed as an argument will be combined using {{bitwise-ior}}.
220An empty list will be passed as 0 (zero). Results of the enum type are
221automatically converted into a scheme value (note that combinations are not
222supported in this case).
223
224{{TYPESPEC}} maybe a TYPENAME symbol or a list of the form {{(SCHEMENAME
225REALTYPE [DEFAULT-SCHEME-VALUE])}}, where {{REALTYPE}} designates the native
226type used. The default type specification is {{(TYPENAME TYPENAME)}}. The
227{{DEFAULT-SCHEME-VALUE}} overrides the default result of mapping from the
228native type; i.e. when no such mapping exists. When supplied the form is used
229unquoted, otherwise the result is {{'()}}.
230
231{{ENUMSPEC}} is a TYPENAME symbol or a list of the form {{(SCHEMENAME REALTYPE
232[SCHEME-VALUE])}}, where {{REALTYPE}} designates the native type used. The
233default enum specification is {{(TYPENAME TYPENAME)}}. The {{SCHEME-VALUE}}
234overrides the result of mapping from the native type. When supplied the form is
235used unquoted, otherwise the {{SCHEMENAME}} symbol is returned.
236
237{{USE-ALIASES}} is an optional boolean flag that determines whether an alias or
238the {{SCHEMENAME}} is used as the defined foreign variable name. The default
239is {{#t}}.
240
241Additionally two procedures are defined named {{SCHEMENAME->number}} and
242{{number->SCHEMENAME}}. {{SCHEMENAME->number}} takes one argument and converts
243a symbol (or a list of symbols) into its numeric value.  {{number->SCHEMENAME}}
244takes one argument and converts a numeric value into its scheme value.
245
246Note that the specification of a scheme value override ({{SCHEME-VALUE}}) means
247the mapping may not be closed! {{(number->SCHEMENAME (SCHEMENAME->number
248SCHEMENAME))}} may not equal {{SCHEMENAME}}.
249
250Here a heavily contrived example:
251
252<enscript highlight=scheme>
253#>
254enum foo { a_foo = 4, b_foo, c_foo };
255enum foo bar(enum foo x) { printf("%d\n", x); return b_foo; }
256<#
257
258(define-foreign-enum (foo (enum "foo")) a_foo b_foo (c c_foo))
259
260(define bar (foreign-lambda foo bar foo))
261
262(pp (bar '()))
263(pp (bar 'a_foo))
264(pp (bar '(b_foo c)))
265</enscript>
266
267
268=== foreign-lambda
269
270 [syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...)
271
272Represents a
273binding to an external routine. This form can be used in the position
274of an ordinary {{lambda}} expression. {{NAME}} specifies the
275name of the external procedure and should be a string or a symbol.
276
277
278=== foreign-lambda*
279
280 [syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
281
282Similar to {{foreign-lambda}}, but instead of generating code to
283call an external function, the body of the C procedure is directly given
284in {{STRING ...}}:
285
286<enscript highlight=scheme>
287(define my-strlen
288  (foreign-lambda* int ((c-string str))
289    "int n = 0;
290     while(*(str++)) ++n;
291     C_return(n);") )
292
293(my-strlen "one two three")             ==> 13
294</enscript>
295
296For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement
297to return a result from the foreign lambda body as some cleanup code has to be run before execution
298commences in the calling code.
299
300=== foreign-safe-lambda
301
302 [syntax] (foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)
303
304This is similar to {{foreign-lambda}}, but also allows the called
305function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
306
307
308=== foreign-safe-lambda*
309
310 [syntax] (foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)
311
312This is similar to {{foreign-lambda*}}, but also allows the called
313function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
314
315
316
317=== foreign-primitive
318
319 [syntax] (foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)
320
321This is also similar to {{foreign-lambda*}} but the code will be executed
322in a ''primitive'' CPS context, which means it will not actually return, but
323call it's continuation on exit. This means that code inside this form may
324allocate Scheme data on the C stack (the ''nursery'') with {{C_alloc}}
325(see below). If the {{RETURNTYPE}} is omitted it defaults to {{void}}.
326You can return multiple values inside the body of the {{foreign-primitive}}
327form by calling this C function:
328
329<enscript highlight=scheme>
330C_values(N + 2, C_SCHEME_UNDEFINED, C_k, X1, ...)
331</enscript>
332
333where {{N}} is the number of values to be returned, and {{X1, ...}} are the
334results, which should be Scheme data objects. When returning multiple values, the
335return-type should be omitted.
336
337
338Previous: [[Interface to external functions and variables]]
339
340Next: [[Foreign type specifiers]]
Note: See TracBrowser for help on using the repository browser.