To simplify embedding compiled Scheme code into arbitrary programs, one
can define so called ``entry points'', which provide a uniform interface
and parameter conversion facilities.
-
- [syntax] (define-entry-point INDEX ((VAR1 TYPE1) ...) (RTYPE1 ...) EXP1 EXP2 ...)
-
Defines a new entry-point with index INDEX which should evaluate
to an exact integer. During execution of the body EXP1 EXP2 ...
the variables VAR1 ... are bound to the parameters passed from
the host program to the invoked entry point. The parameters passed
are converted according to the foreign type specifiers TYPE1
.... The expressions should return as many values as foreign type
specifiers are given in RTYPE1 .... The results are then
transformed into values that can be used in the host program.
Note: if one or more of the result types RTYPE ...
specify the type c-string, then the parameter types at the same
positions in TYPE1 ... have to be c-strings as well,
because the result strings are copied into the same area in memory.
You should also take care that the passed buffer is long enough to hold
the result string or unpredictable things will happen.
If entry points were defined then the program will not terminate after
execution of the last toplevel expression, but instead it will enter a
loop that waits for the host to invoke one of the defined entry points.
The following C functions and data types are provided:
-
- [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.
- [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 or CHICKEN_invoke 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.
- [C function] void CHICKEN_run(void **data, int *bytes, int *maxlen, void *toplevel)
-
Starts the Scheme program. data, bytes and maxlen
contain invocation parameters in raw form. Pass NULL here.
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.
- [C function] void CHICKEN_invoke(int index, C_parameter *params, int count, void *toplevel)
-
Invoke the entry point with index index. count should
contain the number of parameters passed. params is a pointer
to parameter data:
typedef union
{
C_word x; /* parameter type scheme-object */
long i; /* parameter type bool, [unsigned] int/short/long */
long c; /* parameter type [unsigned] char */
double f; /* parameter type float/double */
void *p; /* any pointer parameter type and C strings */
} C_parameter;
This function calls CHICKEN_run if it was not called at least
once before.
Here is a simple example (assuming a UNIX-like environment):
% cat foo.c
#include <stdio.h>
#include "chicken.h"
int main(void)
{
C_parameter p[ 3 ];
char str[ 32 ] = "hello!"; /* We need some space for the result string! */
memset(p, 0, sizeof(p));
p[ 0 ].i = -99;
p[ 1 ].p = str;
p[ 2 ].f = 3.14;
CHICKEN_invoke(1, p, 3, C_toplevel);
printf("->\n%d\n%s\n", p[ 0 ].i, p[ 1 ].p);
return 0;
}
% cat bar.scm
(define-entry-point 1
((a integer) (b c-string) (c double))
(int c-string)
(print (list a b c))
(values 123 "good bye!") )
% chicken bar.scm -quiet
% gcc foo.c bar.c -o foo `chicken-config -cflags -embedded`
% foo
(-99 "hello!" 3.14)
->
123
good bye!
Note the use of -embedded. We have to compile with additional compiler
options, because the host program provides the main
function.