source: project/wiki/Accessing external objects @ 12589

Last change on this file since 12589 was 12589, checked in by svnwiki, 11 years ago

Changes applied for AndreKuehne? (83.135.28.144) through svnwiki:

improved subsection structure of define-foreign-record section

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.
116
117==== slot definitions
118
119A {{SLOT}} definition should be a list of one of the following forms:
120
121 (TYPE SLOTNAME)
122
123or
124
125 (TYPE SLOTNAME SIZE)
126
127The latter form defines an array of {{SIZE}} elements of the type {{TYPE}} embedded in the
128structure.
129For every slot, the following accessor procedures will be generated:
130
131
132===== TYPENAME-SLOTNAME
133
134 (TYPENAME-SLOTNAME FOREIGN-RECORD-POINTER [INDEX])
135
136A procedure of one argument (a pointer to a C structure), that returns
137the slot value of the slot {{SLOTNAME}}. If a {{SIZE}} has been given in the slot definition, then
138an additional argument {{INDEX}} is required that specifies the index of an array-element.
139
140
141===== TYPENAME-SLOTNAME-set!
142 
143 (TYPENAME-SLOTNAME-set! FOREIGN-RECORD-POINTER [INDEX] VALUE)
144
145A procedure of two arguments (a pointer to a C structure) and a value, that
146sets the slot value of the slot {{SLOTNAME}} in the structure. If a {{SIZE}} has been given in
147the slot definition, then an additional argument {{INDEX}} is required for the array index.
148
149If a slot type is of the form {{(const ...)}}, then no setter procedure will be generated.
150Slots of the types {{(struct ...)}} or {{(union ...)}} are accessed as pointers to the embedded
151struct (or union) and no setter will be generated.
152
153
154==== record declarations
155
156Additionally, special record declarations ({{DECL ...}}) may be given, where each declaration consists
157of a list of the form {{(KEYWORD ARGUMENT ...)}}. The available declarations are:
158
159
160===== constructor
161
162 (constructor: NAME)
163
164Generate a constructor-procedure with no arguments that has the name {{NAME}} (a symbol) that returns a pointer to a structure of this
165type. The storage will be allocated with {{malloc(3)}}.
166
167
168===== destructor
169
170 (destructor: NAME)
171
172Generate a destructor function with the name {{NAME}} that takes a pointer to a structure of this
173type as its single argument and releases the storage with {{free(3)}}. If the argument is {{#f}},
174the destructor procedure does nothing.
175
176
177===== rename
178
179 (rename: EXPRESSION)
180
181Evaluates {{EXPRESSION}} at compile-/macro-expansion-time and applies the result, which should be
182a procedure, to the string-representation of the name of each accessor-procedure generated. Another (or the same)
183string should be returned, which in turn is taken as the actual name of the accessor.
184
185
186==== example
187
188<enscript highlight=scheme>
189(require-for-syntax 'srfi-13)
190
191(define-foreign-record Some_Struct
192  (rename: (compose string-downcase (cut string-translate <> "_" "-")))
193  (constructor: make-some-struct)
194  (destructor: free-some-struct)
195  (int xCoord)
196  (int yCoord) )
197</enscript>
198
199will generate the following procedures:
200
201<enscript highlight=scheme>
202(make-some-struct)              --> C-POINTER
203(free-some-struct C-POINTER)
204
205(some-struct-xcoord C-POINTER)  --> NUMBER
206(some-struct-ycoord C-POINTER)  --> NUMBER
207
208(some-struct-xcoord-set! C-POINTER NUMBER)
209(some-struct-ycoord-set! C-POINTER NUMBER)
210</enscript>
211
212
213=== define-foreign-enum
214
215 [syntax] (define-foreign-enum TYPESPEC [USE-ALIASES] ENUMSPEC ...)
216
217Defines a foreign type (as with {{define-foreign-type}}) that maps the elements
218of a C/C++ enum (or a enum-like list of constants) to and from a set of
219symbols.
220
221{{TYPESPEC}} specifies a foreign type that converts a symbol argument from the
222set {{ENUMSPEC ...}} into the appropriate enum value when passed as an argument to
223a foreign function.
224
225A list of symbols passed as an argument will be combined using {{bitwise-ior}}.
226An empty list will be passed as 0 (zero). Results of the enum type are
227automatically converted into a scheme value (note that combinations are not
228supported in this case).
229
230{{TYPESPEC}} maybe a TYPENAME symbol or a list of the form {{(SCHEMENAME
231REALTYPE [DEFAULT-SCHEME-VALUE])}}, where {{REALTYPE}} designates the native
232type used. The default type specification is {{(TYPENAME TYPENAME)}}. The
233{{DEFAULT-SCHEME-VALUE}} overrides the default result of mapping from the
234native type; i.e. when no such mapping exists. When supplied the form is used
235unquoted, otherwise the result is {{'()}}.
236
237{{ENUMSPEC}} is a TYPENAME symbol or a list of the form {{(SCHEMENAME REALTYPE
238[SCHEME-VALUE])}}, where {{REALTYPE}} designates the native type used. The
239default enum specification is {{(TYPENAME TYPENAME)}}. The {{SCHEME-VALUE}}
240overrides the result of mapping from the native type. When supplied the form is
241used unquoted, otherwise the {{SCHEMENAME}} symbol is returned.
242
243{{USE-ALIASES}} is an optional boolean flag that determines whether an alias or
244the {{SCHEMENAME}} is used as the defined foreign variable name. The default
245is {{#t}}.
246
247Additionally two procedures are defined named {{SCHEMENAME->number}} and
248{{number->SCHEMENAME}}. {{SCHEMENAME->number}} takes one argument and converts
249a symbol (or a list of symbols) into its numeric value.  {{number->SCHEMENAME}}
250takes one argument and converts a numeric value into its scheme value.
251
252Note that the specification of a scheme value override ({{SCHEME-VALUE}}) means
253the mapping may not be closed! {{(number->SCHEMENAME (SCHEMENAME->number
254SCHEMENAME))}} may not equal {{SCHEMENAME}}.
255
256Here a heavily contrived example:
257
258<enscript highlight=scheme>
259#>
260enum foo { a_foo = 4, b_foo, c_foo };
261enum foo bar(enum foo x) { printf("%d\n", x); return b_foo; }
262<#
263
264(define-foreign-enum (foo (enum "foo")) a_foo b_foo (c c_foo))
265
266(define bar (foreign-lambda foo bar foo))
267
268(pp (bar '()))
269(pp (bar 'a_foo))
270(pp (bar '(b_foo c)))
271</enscript>
272
273
274=== foreign-lambda
275
276 [syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...)
277
278Represents a
279binding to an external routine. This form can be used in the position
280of an ordinary {{lambda}} expression. {{NAME}} specifies the
281name of the external procedure and should be a string or a symbol.
282
283
284=== foreign-lambda*
285
286 [syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
287
288Similar to {{foreign-lambda}}, but instead of generating code to
289call an external function, the body of the C procedure is directly given
290in {{STRING ...}}:
291
292<enscript highlight=scheme>
293(define my-strlen
294  (foreign-lambda* int ((c-string str))
295    "int n = 0;
296     while(*(str++)) ++n;
297     C_return(n);") )
298
299(my-strlen "one two three")             ==> 13
300</enscript>
301
302For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement
303to return a result from the foreign lambda body as some cleanup code has to be run before execution
304commences in the calling code.
305
306=== foreign-safe-lambda
307
308 [syntax] (foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)
309
310This is similar to {{foreign-lambda}}, but also allows the called
311function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
312
313
314=== foreign-safe-lambda*
315
316 [syntax] (foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)
317
318This is similar to {{foreign-lambda*}}, but also allows the called
319function to call Scheme functions and allocate Scheme data-objects. See [[Callbacks]].
320
321
322
323=== foreign-primitive
324
325 [syntax] (foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)
326
327This is also similar to {{foreign-lambda*}} but the code will be executed
328in a ''primitive'' CPS context, which means it will not actually return, but
329call it's continuation on exit. This means that code inside this form may
330allocate Scheme data on the C stack (the ''nursery'') with {{C_alloc}}
331(see below). If the {{RETURNTYPE}} is omitted it defaults to {{void}}.
332You can return multiple values inside the body of the {{foreign-primitive}}
333form by calling this C function:
334
335<enscript highlight=scheme>
336C_values(N + 2, C_SCHEME_UNDEFINED, C_k, X1, ...)
337</enscript>
338
339where {{N}} is the number of values to be returned, and {{X1, ...}} are the
340results, which should be Scheme data objects. When returning multiple values, the
341return-type should be omitted.
342
343
344Previous: [[Interface to external functions and variables]]
345
346Next: [[Foreign type specifiers]]
Note: See TracBrowser for help on using the repository browser.