~ chicken-core (chicken-5) /manual/Embedding
Trap1[[tags: manual]]2[[toc:]]345== Embedding67Compiled Scheme files can be linked with C code, provided the Scheme8code was compiled in ''embedded'' mode by passing {{-DC_EMBEDDED}} to9the C compiler (this will disable generation of a {{main()}}10function). {{csc}} will do this, when given the {{-embedded}} option.1112The following C API is available:1314=== CHICKEN_parse_command_line1516 [C function] void CHICKEN_parse_command_line (int argc, char *argv[], int *heap, int *stack int *symbols)1718Parse the programs command-line contained in {{argc}} and19{{argv}} and return the heap-, stack- and symbol table limits20given by runtime options of the form {{-:...}}, or choose default21limits. The library procedure {{argv}} can access the command-line22only if this function has been called by the containing application.232425=== CHICKEN_initialize2627 [C function] int CHICKEN_initialize (int heap, int stack, int symbols, void *toplevel)2829Initializes the Scheme execution context and memory. {{heap}} holds30the number of bytes that are to be allocated for the secondary31heap. {{stack}} holds the number of bytes for the primary32heap. {{symbols}} contains the size of the symbol table. The keyword33table will be 1/4th the symbol table size. Passing {{0}} to one or34more of these parameters will select a default size.3536{{toplevel}} should be a pointer to the toplevel entry point37procedure. You should pass {{C_toplevel}} here. In any subsequent38call to {{CHICKEN_run}} you can simply39pass {{NULL}}.40Calling this function more than once has no effect. If enough41memory is available and initialization was successful, then {{1}}42is returned, otherwise this function returns {{0}}.4344It is essential to run {{CHICKEN_initialize}} and subsequent calls to45{{CHICKEN_run}} in the same native thread. The former computes a stack46limit address which will not be valid if the runtime system is47re-entered in a execution context where the stack is located at a48different address.4950=== CHICKEN_run5152 [C function] C_word CHICKEN_run (void *toplevel)5354Starts the Scheme program. Call this function once to execute all toplevel expressions in your55compiled 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 the59point after it called [[Module (chicken platform)#return-to-host|{{return-to-host}}]].6061If you just need a Scheme interpreter, you can also pass {{CHICKEN_default_toplevel}} as62the toplevel procedure, which just uses the default library units.6364Once {{CHICKEN_run}} has been called, Scheme code is executing until all toplevel65expressions have been evaluated or until {{return-to-host}} is called inside the66Scheme program.6768=== CHICKEN_eval6970 [C macro] int CHICKEN_eval (C_word exp, C_word *result)7172Evaluates 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 description75of the error.767778=== CHICKEN_eval_string7980 [C macro] int CHICKEN_eval_string (char *str, C_word *result)8182Evaluates the Scheme expression passed in the string {{str}}, writing the result value to {{result}}.838485=== CHICKEN_eval_to_string8687 [C macro] int CHICKEN_eval_to_string (C_word exp, char *result, int size)8889Evaluates the Scheme expression passed in {{exp}}, writing a textual representation90of the result into {{result}}. {{size}} should specify the maximal size of the result string.919293=== CHICKEN_eval_string_to_string9495 [C macro] int CHICKEN_eval_string_to_string (char *str, char *result, int size)9697Evaluates the Scheme expression passed in the string {{str}}, writing a textual representation98of the result into {{result}}. {{size}} should specify the maximal size of the result string.99100101=== CHICKEN_apply102103 [C macro] int CHICKEN_apply (C_word func, C_word args, C_word *result)104105Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing the result value to {{result}}.106107108=== CHICKEN_apply_to_string109110 [C macro] int CHICKEN_apply_to_string (C_word func, C_word args, char *result, int size)111112Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing a textual113representation of the result into {{result}}.114115116=== CHICKEN_read117118 [C macro] int CHICKEN_read (char *str, C_word *result)119120Reads a Scheme object from the string {{str}}, writing the result value to {{result}}.121122123=== CHICKEN_load124125 [C macro] int CHICKEN_load (char *filename)126127Loads the Scheme file {{filename}} (either in source form or compiled).128129130=== CHICKEN_get_error_message131132 [C macro] void CHICKEN_get_error_message (char *result, int size)133134Returns a textual description of the most recent error that occurred in executing embedded Scheme code.135136137=== CHICKEN_yield138139 [C macro] int CHICKEN_yield (int *status)140141If threads have been spawned during earlier invocations of embedded Scheme code, then this function142will run the next scheduled thread for one complete time-slice. This is useful, for example, inside143an ''idle'' handler in a GUI application with background Scheme threads.144145146147An example:148149 % cat x.scm150 ;;; x.scm151 (import (chicken platform) (chicken foreign))152153 (define (bar x) (gc) (* x x))154155 (define-external (baz (int i)) double156 (sqrt i))157 (return-to-host)158159160 % cat y.c161 /* y.c */162163 #include <chicken.h>164 #include <assert.h>165166 extern double baz(int);167168 int main() {169 char buffer[ 256 ];170 int status;171 C_word val = C_SCHEME_UNDEFINED;172 C_word *data[ 1 ];173174 data[ 0 ] = &val;175176 CHICKEN_run(C_toplevel);177178 status = CHICKEN_read("(bar 99)", &val);179 assert(status);180181 C_gc_protect(data, 1);182183 printf("data: %08x\n", val);184185 status = CHICKEN_eval_string_to_string("(bar)", buffer, 255);186 assert(!status);187188 CHICKEN_get_error_message(buffer, 255);189 printf("ouch: %s\n", buffer);190191 status = CHICKEN_eval_string_to_string("(bar 23)", buffer, 255);192 assert(status);193194 printf("-> %s\n", buffer);195 printf("data: %08x\n", val);196197 status = CHICKEN_eval_to_string(val, buffer, 255);198 assert(status);199 printf("-> %s\n", buffer);200201 printf("->` %g\n", baz(22));202203 return 0;204 }205206 % csc x.scm y.c -embedded207208It is also possible to re-enter the computation following the call to {{return-to-host}} by calling209{{CHICKEN_continue}}:210211=== CHICKEN_continue212213 [C function] C_word CHICKEN_continue (C_word k)214215Re-enters Scheme execution. {{k}} is the continuation received from the previous invocation216of {{CHICKEN_run}} or {{CHICKEN_continue}}. When {{return-to-host}} is called again,217this function returns another continuation that can be used to restart again.218219If you invoke callbacks prior to calling {{CHICKEN_continue}}, make sure that the220continuation is not reclaimed by garbage collection. This can be avoided by using {{C_gc_protect}}221or gc-roots.222223Another example:224225 % cat x.scm226 (import (chicken platform) srfi-18) ;; Needs the srfi-18 egg227228 (define m (make-mutex))229230 (define (t)231 (mutex-lock! m)232 (thread-sleep! 1)233 (print (thread-name (current-thread)))234 (mutex-unlock! m)235 (t) )236237 (thread-start! (make-thread t 'PING!))238 (thread-start! (make-thread t 'PONG!))239240 (let loop ()241 (return-to-host)242 (thread-yield!)243 (loop) )244245 % cat y.c246 #include <chicken.h>247248 int main()249 {250 C_word k = CHICKEN_run(C_toplevel);251252 for(;;)253 k = CHICKEN_continue(k);254255 return 0;256 }257258 % csc x.scm y.c -embedded259260It 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 system262and any Scheme code executed prior to the invocation is initialized and can be conveniently263used via callbacks.264265A simpler interface For handling GC-safe references to Scheme data are the so called ''gc-roots'':266267=== CHICKEN_new_gc_root268269 [C function] void* CHICKEN_new_gc_root ()270271Returns a pointer to a ''GC root'', which is an object that holds a reference to a Scheme value272that will always be valid, even after a garbage collection. The content of the gc root is initialized to273an unspecified value.274275276=== CHICKEN_new_finalizable_gc_root277278 [C function] void* CHICKEN_new_finalizable_gc_root ()279280Similar to {{CHICKEN_new_gc_root}}, but allows the stored value to281be finalized: if this gc root holds reference to an otherwise282unreferenced data object that has a finalizer, the finalizer is still283invoked.284285286=== CHICKEN_delete_gc_root287288 [C function] void CHICKEN_delete_gc_root (void *root)289290Deletes the gc root.291292293=== CHICKEN_gc_root_ref294295 [C macro] C_word CHICKEN_gc_root_ref (void *root)296297Returns the value stored in the gc root.298299300=== CHICKEN_gc_root_set301302 [C macro] void CHICKEN_gc_root_set (void *root, C_word value)303304Sets the content of the GC root to a new value.305306307308Sometimes it is handy to access global variables from C code:309310=== CHICKEN_global_lookup311312 [C function] void* CHICKEN_global_lookup (char *name)313314Returns a GC root that holds the global variable with the name {{name}}. If no such variable315exists, {{NULL}} is returned.316317318=== CHICKEN_global_ref319320 [C function] C_word CHICKEN_global_ref (void *global)321322Returns the value of the global variable referenced by the GC root {{global}}.323324325=== CHICKEN_global_set326327 [C function] void CHICKEN_global_set (void *global, C_word value)328329Sets the value of the global variable referenced by the GC root {{global}} to {{value}}.330331---332Previous: [[Foreign type specifiers]]333334Next: [[C interface]]