~ chicken-core (chicken-5) /manual/Embedding


  1[[tags: manual]]
  2[[toc:]]
  3
  4
  5== Embedding
  6
  7Compiled Scheme files can be linked with C code, provided the Scheme
  8code was compiled in ''embedded'' mode by passing {{-DC_EMBEDDED}} to
  9the C compiler (this will disable generation of a {{main()}}
 10function). {{csc}} will do this, when given the {{-embedded}} option.
 11
 12The following C API is available:
 13
 14=== CHICKEN_parse_command_line
 15
 16 [C function] void CHICKEN_parse_command_line (int argc, char *argv[], int *heap, int *stack int *symbols)
 17
 18Parse the programs command-line contained in {{argc}} and
 19{{argv}} and return the heap-, stack- and symbol table limits
 20given by runtime options of the form {{-:...}}, or choose default
 21limits. The library procedure {{argv}} can access the command-line
 22only if this function has been called by the containing application.
 23
 24
 25=== CHICKEN_initialize
 26
 27 [C function] int CHICKEN_initialize (int heap, int stack, int symbols, void *toplevel) 
 28
 29Initializes the Scheme execution context and memory. {{heap}} holds
 30the number of bytes that are to be allocated for the secondary
 31heap. {{stack}} holds the number of bytes for the primary
 32heap. {{symbols}} contains the size of the symbol table. The keyword
 33table will be 1/4th the symbol table size.  Passing {{0}} to one or
 34more of these parameters will select a default size.
 35
 36{{toplevel}} should be a pointer to the toplevel entry point
 37procedure. You should pass {{C_toplevel}} here. In any subsequent
 38call to {{CHICKEN_run}} you can simply
 39pass {{NULL}}.
 40Calling this function more than once has no effect. If enough
 41memory is available and initialization was successful, then {{1}}
 42is returned, otherwise this function returns {{0}}.
 43
 44It is essential to run {{CHICKEN_initialize}} and subsequent calls to
 45{{CHICKEN_run}} in the same native thread. The former computes a stack
 46limit address which will not be valid if the runtime system is
 47re-entered in a execution context where the stack is located at a
 48different address.
 49
 50=== CHICKEN_run
 51
 52 [C function] C_word CHICKEN_run (void *toplevel)
 53
 54Starts the Scheme program. Call this function once to execute all toplevel expressions in your
 55compiled Scheme program. If the runtime system was not initialized before,
 56then {{CHICKEN_initialize}} is called with default sizes.
 57{{toplevel}} is the toplevel entry-point procedure, you usually pass {{C_toplevel}} here.
 58The result value is the continuation that can be used to re-invoke the Scheme code from the
 59point after it called [[Module (chicken platform)#return-to-host|{{return-to-host}}]].
 60
 61If you just need a Scheme interpreter, you can also pass {{CHICKEN_default_toplevel}} as
 62the toplevel procedure, which just uses the default library units.
 63
 64Once {{CHICKEN_run}} has been called, Scheme code is executing until all toplevel
 65expressions have been evaluated or until {{return-to-host}} is called inside the
 66Scheme program.
 67
 68=== CHICKEN_eval
 69
 70 [C macro] int CHICKEN_eval (C_word exp, C_word *result)
 71
 72Evaluates the Scheme object passed in {{exp}}, writing the result value to {{result}}.
 73The return value is 1 if the operation succeeded,
 74or 0 if an error occurred. Call {{CHICKEN_get_error_message}} to obtain a description
 75of the error.
 76
 77
 78=== CHICKEN_eval_string
 79
 80 [C macro] int CHICKEN_eval_string (char *str, C_word *result)
 81
 82Evaluates the Scheme expression passed in the string {{str}}, writing the result value to {{result}}.
 83
 84
 85=== CHICKEN_eval_to_string
 86
 87 [C macro] int CHICKEN_eval_to_string (C_word exp, char *result, int size)
 88
 89Evaluates the Scheme expression passed in {{exp}}, writing a textual representation
 90of the result into {{result}}. {{size}} should specify the maximal size of the result string.
 91
 92
 93=== CHICKEN_eval_string_to_string
 94
 95 [C macro] int CHICKEN_eval_string_to_string (char *str, char *result, int size)
 96
 97Evaluates the Scheme expression passed in the string {{str}}, writing a textual representation
 98of the result into {{result}}. {{size}} should specify the maximal size of the result string.
 99
100
101=== CHICKEN_apply
102
103 [C macro] int CHICKEN_apply (C_word func, C_word args, C_word *result)
104
105Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing the result value to {{result}}.
106
107
108=== CHICKEN_apply_to_string
109
110 [C macro] int CHICKEN_apply_to_string (C_word func, C_word args, char *result, int size)
111
112Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing a textual 
113representation of the result into {{result}}.
114
115
116=== CHICKEN_read
117
118 [C macro] int CHICKEN_read (char *str, C_word *result)
119
120Reads a Scheme object from the string {{str}}, writing the result value to {{result}}.
121
122
123=== CHICKEN_load
124
125 [C macro] int CHICKEN_load (char *filename)
126
127Loads the Scheme file {{filename}} (either in source form or compiled).
128
129
130=== CHICKEN_get_error_message
131
132 [C macro] void CHICKEN_get_error_message (char *result, int size)
133
134Returns a textual description of the most recent error that occurred in executing embedded Scheme code.
135
136
137=== CHICKEN_yield
138
139 [C macro] int CHICKEN_yield (int *status)
140
141If threads have been spawned during earlier invocations of embedded Scheme code, then this function
142will run the next scheduled thread for one complete time-slice. This is useful, for example, inside
143an ''idle'' handler in a GUI application with background Scheme threads.
144
145
146
147An example:
148
149 % cat x.scm
150 ;;; x.scm
151 (import (chicken platform) (chicken foreign))
152 
153 (define (bar x) (gc) (* x x))
154 
155 (define-external (baz (int i)) double
156   (sqrt i))
157 (return-to-host)
158 
159
160 % cat y.c
161 /* y.c */
162 
163 #include <chicken.h>
164 #include <assert.h>
165 
166 extern double baz(int);
167 
168 int main() {
169   char buffer[ 256 ];
170   int status;
171   C_word val = C_SCHEME_UNDEFINED;
172   C_word *data[ 1 ];
173 
174   data[ 0 ] = &val;
175 
176   CHICKEN_run(C_toplevel);
177 
178   status = CHICKEN_read("(bar 99)", &val);
179   assert(status);
180 
181   C_gc_protect(data, 1);
182 
183   printf("data: %08x\n", val);
184 
185   status = CHICKEN_eval_string_to_string("(bar)", buffer, 255);
186   assert(!status);
187 
188   CHICKEN_get_error_message(buffer, 255);
189   printf("ouch: %s\n", buffer);
190 
191   status = CHICKEN_eval_string_to_string("(bar 23)", buffer, 255);
192   assert(status);
193 
194   printf("-> %s\n", buffer);
195   printf("data: %08x\n", val);
196 
197   status = CHICKEN_eval_to_string(val, buffer, 255);
198   assert(status);
199   printf("-> %s\n", buffer);
200 
201   printf("->` %g\n", baz(22));
202 
203   return 0;
204 }
205 
206 % csc x.scm y.c -embedded
207
208It is also possible to re-enter the computation following the call to {{return-to-host}} by calling
209{{CHICKEN_continue}}:
210
211=== CHICKEN_continue
212
213 [C function] C_word CHICKEN_continue (C_word k)
214
215Re-enters Scheme execution. {{k}} is the continuation received from the previous invocation
216of {{CHICKEN_run}} or {{CHICKEN_continue}}. When {{return-to-host}} is called again,
217this function returns another continuation that can be used to restart again.
218
219If you invoke callbacks prior to calling {{CHICKEN_continue}}, make sure that the
220continuation is not reclaimed by garbage collection. This can be avoided by using {{C_gc_protect}}
221or gc-roots.
222
223Another example:
224
225 % cat x.scm
226 (import (chicken platform) srfi-18) ;; Needs the srfi-18 egg
227 
228 (define m (make-mutex))
229 
230 (define (t)
231   (mutex-lock! m)
232   (thread-sleep! 1)
233   (print (thread-name (current-thread)))
234   (mutex-unlock! m)
235   (t) )
236 
237 (thread-start! (make-thread t 'PING!))
238 (thread-start! (make-thread t 'PONG!))
239 
240 (let loop ()
241   (return-to-host)
242   (thread-yield!)
243   (loop) )
244 
245 % cat y.c
246 #include <chicken.h>
247 
248 int main()
249 {
250   C_word k = CHICKEN_run(C_toplevel);
251 
252   for(;;)
253     k = CHICKEN_continue(k);
254 
255   return 0;
256 }
257 
258 % csc x.scm y.c -embedded
259
260It is advisable not to mix repeated uses of {{CHICKEN_continue}}/{{return-to-host}}
261(as in the example above) with callbacks. Once {{return-to-host}} is invoked, the runtime system
262and any Scheme code executed prior to the invocation is initialized and can be conveniently
263used via callbacks.
264
265A simpler interface For handling GC-safe references to Scheme data are the so called ''gc-roots'':
266
267=== CHICKEN_new_gc_root
268
269 [C function] void* CHICKEN_new_gc_root ()
270
271Returns a pointer to a ''GC root'', which is an object that holds a reference to a Scheme value
272that will always be valid, even after a garbage collection. The content of the gc root is initialized to
273an unspecified value.
274
275
276=== CHICKEN_new_finalizable_gc_root
277
278 [C function] void* CHICKEN_new_finalizable_gc_root ()
279
280Similar to {{CHICKEN_new_gc_root}}, but allows the stored value to
281be finalized: if this gc root holds reference to an otherwise
282unreferenced data object that has a finalizer, the finalizer is still
283invoked.
284
285
286=== CHICKEN_delete_gc_root
287
288 [C function] void CHICKEN_delete_gc_root (void *root)
289
290Deletes the gc root.
291
292
293=== CHICKEN_gc_root_ref
294
295 [C macro] C_word CHICKEN_gc_root_ref (void *root)
296
297Returns the value stored in the gc root.
298
299
300=== CHICKEN_gc_root_set
301
302 [C macro] void CHICKEN_gc_root_set (void *root, C_word value)
303
304Sets the content of the GC root to a new value.
305
306
307
308Sometimes it is handy to access global variables from C code:
309
310=== CHICKEN_global_lookup
311
312 [C function] void* CHICKEN_global_lookup (char *name)
313
314Returns a GC root that holds the global variable with the name {{name}}. If no such variable
315exists, {{NULL}} is returned.
316
317
318=== CHICKEN_global_ref
319
320 [C function] C_word CHICKEN_global_ref (void *global)
321
322Returns the value of the global variable referenced by the GC root {{global}}.
323
324
325=== CHICKEN_global_set
326
327 [C function] void CHICKEN_global_set (void *global, C_word value)
328
329Sets the value of the global variable referenced by the GC root {{global}} to {{value}}.
330
331---
332Previous: [[Foreign type specifiers]]
333
334Next: [[C interface]]
Trap