[[tags: manual]]
[[toc:]]


== Embedding

Compiled Scheme files can be linked with C code, provided the Scheme code was compiled
in ''embedded'' mode by passing {{-DC_EMBEDDED}} to the C compiler (this will
disable generation of a {{main()}} function). {{csc}} will do this, when given
the {{-embedded}} option. Alternatively pass {{-embedded}} to {{csc}}.

The following C API is available:

=== CHICKEN_parse_command_line

 [C function] void CHICKEN_parse_command_line (int argc, char *argv[], int *heap, int *stack int *symbols)

Parse the programs command-line contained in {{argc}} and
{{argv}} and return the heap-, stack- and symbol table limits
given by runtime options of the form {{-:...}}, or choose default
limits. The library procedure {{argv}} can access the command-line
only if this function has been called by the containing application.


=== CHICKEN_initialize

 [C function] int CHICKEN_initialize (int heap, int stack, int symbols, void *toplevel) 

Initializes the Scheme execution context and memory. {{heap}}
holds the number of bytes that are to be allocated for the secondary
heap. {{stack}} holds the number of bytes for the primary
heap. {{symbols}} contains the size of the symbol table. Passing
{{0}} to one or more of these parameters will select a default
size. 
{{toplevel}} should be a pointer to the toplevel entry point
procedure. You should pass {{C_toplevel}} here. In any subsequent
call to {{CHICKEN_run}} you can simply
pass {{NULL}}.
Calling this function more than once has no effect. If enough
memory is available and initialization was successful, then {{1}}
is returned, otherwise this function returns {{0}}.

=== CHICKEN_run

 [C function] C_word CHICKEN_run (void *toplevel)

Starts the Scheme program. Call this function once to execute all toplevel expressions in your
compiled Scheme program. If the runtime system was not initialized before,
then {{CHICKEN_initialize}} is called with default sizes.
{{toplevel}} is the toplevel entry-point procedure, you usually pass {{C_toplevel}} here.
The result value is the continuation that can be used to re-invoke the Scheme code from the
point after it called {{return-to-host}} (see below).

If you just need a Scheme interpreter, you can also pass {{CHICKEN_default_toplevel}} as
the toplevel procedure, which just uses the default library units.


Once {{CHICKEN_run}} has been called, Scheme code is executing until all toplevel
expressions have been evaluated or until {{return-to-host}} is called inside the
Scheme program.

=== return-to-host

<procedure>(return-to-host)</procedure>

Exits the Scheme code and returns to the invoking context that called {{CHICKEN_run}}
or {{CHICKEN_continue}}.

After {{return-to-host}} has been executed and once {{CHICKEN_run}} returns,
you can invoke callbacks which have been defined with {{define-external}}.
The {{eval}} library unit also provides ''boilerplate'' callbacks, that simplify invoking Scheme
code embedded in a C or C++ application a lot.

=== CHICKEN_eval

 [C macro] int CHICKEN_eval (C_word exp, C_word *result)

Evaluates the Scheme object passed in {{exp}}, writing the result value to {{result}}.
The return value is 1 if the operation succeeded,
or 0 if an error occurred. Call {{CHICKEN_get_error_message}} to obtain a description
of the error.


=== CHICKEN_eval_string

 [C macro] int CHICKEN_eval_string (char *str, C_word *result)

Evaluates the Scheme expression passed in the string {{str}}, writing the result value to {{result}}.


=== CHICKEN_eval_to_string

 [C macro] int CHICKEN_eval_to_string (C_word exp, char *result, int size)

Evaluates the Scheme expression passed in {{exp}}, writing a textual representation
of the result into {{result}}. {{size}} should specify the maximal size of the result string.


=== CHICKEN_eval_string_to_string

 [C macro] int CHICKEN_eval_string_to_string (char *str, char *result, int size)

Evaluates the Scheme expression passed in the string {{str}}, writing a textual representation
of the result into {{result}}. {{size}} should specify the maximal size of the result string.


=== CHICKEN_apply

 [C macro] int CHICKEN_apply (C_word func, C_word args, C_word *result)

Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing the result value to {{result}}.


=== CHICKEN_apply_to_string

 [C macro] int CHICKEN_apply_to_string (C_word func, C_word args, char *result, int size)

Applies the procedure passed in {{func}} to the list of arguments {{args}}, writing a textual 
representation of the result into {{result}}.


=== CHICKEN_read

 [C macro] int CHICKEN_read (char *str, C_word *result)

Reads a Scheme object from the string {{str}}, writing the result value to {{result}}.


=== CHICKEN_load

 [C macro] int CHICKEN_load (char *filename)

Loads the Scheme file {{filename}} (either in source form or compiled).


=== CHICKEN_get_error_message

 [C macro] void CHICKEN_get_error_message (char *result, int size)

Returns a textual description of the most recent error that occurred in executing embedded Scheme code.


=== CHICKEN_yield

 [C macro] int CHICKEN_yield (int *status)

If threads have been spawned during earlier invocations of embedded Scheme code, then this function
will run the next scheduled thread for one complete time-slice. This is useful, for example, inside
an ''idle'' handler in a GUI application with background Scheme threads. Note that the 
{{srfi-18}} library unit has to be linked in for this.



An example:

 % cat x.scm
 ;;; x.scm
 
 (define (bar x) (gc) (* x x))
 
 (define-external (baz (int i)) double
   (sqrt i))
 (return-to-host)
 

 % cat y.c
 /* y.c */
 
 #include <chicken.h>
 #include <assert.h>
 
 extern double baz(int);
 
 int main() {
   char buffer[ 256 ];
   int status;
   C_word val = C_SCHEME_UNDEFINED;
   C_word *data[ 1 ];
 
   data[ 0 ] = &val;
 
   CHICKEN_run(C_toplevel);
 
   status = CHICKEN_read("(bar 99)", &val);
   assert(status);
 
   C_gc_protect(data, 1);
 
   printf("data: %08x\n", val);
 
   status = CHICKEN_eval_string_to_string("(bar)", buffer, 255);
   assert(!status);
 
   CHICKEN_get_error_message(buffer, 255);
   printf("ouch: %s\n", buffer);
 
   status = CHICKEN_eval_string_to_string("(bar 23)", buffer, 255);
   assert(status);
 
   printf("-> %s\n", buffer);
   printf("data: %08x\n", val);
 
   status = CHICKEN_eval_to_string(val, buffer, 255);
   assert(status);
   printf("-> %s\n", buffer);
 
   printf("->` %g\n", baz(22));
 
   return 0;
 }
 
 % csc x.scm y.c -embedded

It is also possible to re-enter the computation following the call to {{return-to-host}} by calling
{{CHICKEN_continue}}:

=== CHICKEN_continue

 [C function] C_word CHICKEN_continue (C_word k)

Re-enters Scheme execution. {{k}} is the continuation received from the previous invocation
of {{CHICKEN_run}} or {{CHICKEN_continue}}. When {{return-to-host}} is called again,
this function returns another continuation that can be used to restart again.

If you invoke callbacks prior to calling {{CHICKEN_continue}}, make sure that the
continuation is not reclaimed by garbage collection. This can be avoided by using {{C_gc_protect}}
or gc-roots.

Another example:

 % cat x.scm
 (require-extension srfi-18)
 
 (define m (make-mutex))
 
 (define (t)
   (mutex-lock! m)
   (thread-sleep! 1)
   (print (thread-name (current-thread)))
   (mutex-unlock! m)
   (t) )
 
 (thread-start! (make-thread t 'PING!))
 (thread-start! (make-thread t 'PONG!))
 
 (let loop ()
   (return-to-host)
   (thread-yield!)
   (loop) )
 
 % cat y.c
 #include <chicken.h>
 
 int main()
 {
   C_word k = CHICKEN_run(C_toplevel);
 
   for(;;)
     k = CHICKEN_continue(k);
 
   return 0;
 }
 
 % csc x.scm y.c -embedded

It is advisable not to mix repeated uses of {{CHICKEN_continue}}/{{return-to-host}}
(as in the example above) with callbacks. Once {{return-to-host}} is invoked, the runtime system
and any Scheme code executed prior to the invocation is initialized and can be conveniently
used via callbacks.

A simpler interface For handling GC-safe references to Scheme data are the so called ''gc-roots'':

=== CHICKEN_new_gc_root

 [C function] void* CHICKEN_new_gc_root ()

Returns a pointer to a ''GC root'', which is an object that holds a reference to a Scheme value
that will always be valid, even after a garbage collection. The content of the gc root is initialized to
an unspecified value.


=== CHICKEN_new_finalizable_gc_root

 [C function] void* CHICKEN_new_finalizable_gc_root ()

Similar to {{CHICKEN_new_gc_root}}, but allows the stored value to
be finalized: if this gc root holds reference to an otherwise
unreferenced data object that has a finalizer, the finalizer is still
invoked.


=== CHICKEN_delete_gc_root

 [C function] void CHICKEN_delete_gc_root (void *root)

Deletes the gc root.


=== CHICKEN_gc_root_ref

 [C macro] C_word CHICKEN_gc_root_ref (void *root)

Returns the value stored in the gc root.


=== CHICKEN_gc_root_set

 [C macro] void CHICKEN_gc_root_set (void *root, C_word value)

Sets the content of the GC root to a new value.



Sometimes it is handy to access global variables from C code:

=== CHICKEN_global_lookup

 [C function] void* CHICKEN_global_lookup (char *name)

Returns a GC root that holds the global variable with the name {{name}}. If no such variable
exists, {{NULL}} is returned.


=== CHICKEN_global_ref

 [C function] C_word CHICKEN_global_ref (void *global)

Returns the value of the global variable referenced by the GC root {{global}}.


=== CHICKEN_global_set

 [C function] void CHICKEN_global_set (void *global, C_word value)

Sets the value of the global variable referenced by the GC root {{global}} to {{value}}.

---
Previous: [[Foreign type specifiers]]

Next: [[Callbacks]]
