File: Embedding.html

package info (click to toggle)
chicken 5.2.0-2
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 32,804 kB
  • sloc: ansic: 579,676; lisp: 71,716; tcl: 1,445; sh: 576; makefile: 58
file content (125 lines) | stat: -rw-r--r-- 13,998 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="manual.css" type="text/css" /></head>
<title>Chicken &raquo; Embedding</title>
<meta name="viewport" content="initial-scale=1" /></html>
<body>
<div id="body">
<div id="main">
<div id="toc">
<h2 class="toc">TOC &raquo;</h2>
<ul class="toc">
<li><a href="#sec:Embedding">Embedding</a>
<ul>
<li><a href="#sec:CHICKEN_parse_command_line">CHICKEN_parse_command_line</a></li>
<li><a href="#sec:CHICKEN_initialize">CHICKEN_initialize</a></li>
<li><a href="#sec:CHICKEN_run">CHICKEN_run</a></li>
<li><a href="#sec:CHICKEN_eval">CHICKEN_eval</a></li>
<li><a href="#sec:CHICKEN_eval_string">CHICKEN_eval_string</a></li>
<li><a href="#sec:CHICKEN_eval_to_string">CHICKEN_eval_to_string</a></li>
<li><a href="#sec:CHICKEN_eval_string_to_string">CHICKEN_eval_string_to_string</a></li>
<li><a href="#sec:CHICKEN_apply">CHICKEN_apply</a></li>
<li><a href="#sec:CHICKEN_apply_to_string">CHICKEN_apply_to_string</a></li>
<li><a href="#sec:CHICKEN_read">CHICKEN_read</a></li>
<li><a href="#sec:CHICKEN_load">CHICKEN_load</a></li>
<li><a href="#sec:CHICKEN_get_error_message">CHICKEN_get_error_message</a></li>
<li><a href="#sec:CHICKEN_yield">CHICKEN_yield</a></li>
<li><a href="#sec:CHICKEN_continue">CHICKEN_continue</a></li>
<li><a href="#sec:CHICKEN_new_gc_root">CHICKEN_new_gc_root</a></li>
<li><a href="#sec:CHICKEN_new_finalizable_gc_root">CHICKEN_new_finalizable_gc_root</a></li>
<li><a href="#sec:CHICKEN_delete_gc_root">CHICKEN_delete_gc_root</a></li>
<li><a href="#sec:CHICKEN_gc_root_ref">CHICKEN_gc_root_ref</a></li>
<li><a href="#sec:CHICKEN_gc_root_set">CHICKEN_gc_root_set</a></li>
<li><a href="#sec:CHICKEN_global_lookup">CHICKEN_global_lookup</a></li>
<li><a href="#sec:CHICKEN_global_ref">CHICKEN_global_ref</a></li>
<li><a href="#sec:CHICKEN_global_set">CHICKEN_global_set</a></li></ul></li></ul></div><h2 id="sec:Embedding"><a href="#sec:Embedding">Embedding</a></h2><p>Compiled Scheme files can be linked with C code, provided the Scheme code was compiled in <i>embedded</i> mode by passing <tt>-DC_EMBEDDED</tt> to the C compiler (this will disable generation of a <tt>main()</tt> function). <tt>csc</tt> will do this, when given the <tt>-embedded</tt> option.</p><p>The following C API is available:</p><h3 id="sec:CHICKEN_parse_command_line"><a href="#sec:CHICKEN_parse_command_line">CHICKEN_parse_command_line</a></h3><pre>[C function] void CHICKEN_parse_command_line (int argc, char *argv[], int *heap, int *stack int *symbols)</pre><p>Parse the programs command-line contained in <tt>argc</tt> and <tt>argv</tt> and return the heap-, stack- and symbol table limits given by runtime options of the form <tt>-:...</tt>, or choose default limits. The library procedure <tt>argv</tt> can access the command-line only if this function has been called by the containing application.</p><h3 id="sec:CHICKEN_initialize"><a href="#sec:CHICKEN_initialize">CHICKEN_initialize</a></h3><pre>[C function] int CHICKEN_initialize (int heap, int stack, int symbols, void *toplevel) </pre><p>Initializes the Scheme execution context and memory. <tt>heap</tt> holds the number of bytes that are to be allocated for the secondary heap. <tt>stack</tt> holds the number of bytes for the primary heap. <tt>symbols</tt> contains the size of the symbol table. The keyword table will be 1/4th the symbol table size.  Passing <tt>0</tt> to one or more of these parameters will select a default size.</p><p><tt>toplevel</tt> should be a pointer to the toplevel entry point procedure. You should pass <tt>C_toplevel</tt> here. In any subsequent call to <tt>CHICKEN_run</tt> you can simply pass <tt>NULL</tt>. Calling this function more than once has no effect. If enough memory is available and initialization was successful, then <tt>1</tt> is returned, otherwise this function returns <tt>0</tt>.</p><p>It is essential to run <tt>CHICKEN_initialize</tt> and subsequent calls to <tt>CHICKEN_run</tt> in the same native thread. The former computes a stack limit address which will not be valid if the runtime system is re-entered in a execution context where the stack is located at a different address.</p><h3 id="sec:CHICKEN_run"><a href="#sec:CHICKEN_run">CHICKEN_run</a></h3><pre>[C function] C_word CHICKEN_run (void *toplevel)</pre><p>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 <tt>CHICKEN_initialize</tt> is called with default sizes. <tt>toplevel</tt> is the toplevel entry-point procedure, you usually pass <tt>C_toplevel</tt> here. The result value is the continuation that can be used to re-invoke the Scheme code from the point after it called <a href="Module%20%28chicken%20platform%29.html#sec:return-to-host"><tt>return-to-host</tt></a>.</p><p>If you just need a Scheme interpreter, you can also pass <tt>CHICKEN_default_toplevel</tt> as the toplevel procedure, which just uses the default library units.</p><p>Once <tt>CHICKEN_run</tt> has been called, Scheme code is executing until all toplevel expressions have been evaluated or until <tt>return-to-host</tt> is called inside the Scheme program.</p><h3 id="sec:CHICKEN_eval"><a href="#sec:CHICKEN_eval">CHICKEN_eval</a></h3><pre>[C macro] int CHICKEN_eval (C_word exp, C_word *result)</pre><p>Evaluates the Scheme object passed in <tt>exp</tt>, writing the result value to <tt>result</tt>. The return value is 1 if the operation succeeded, or 0 if an error occurred. Call <tt>CHICKEN_get_error_message</tt> to obtain a description of the error.</p><h3 id="sec:CHICKEN_eval_string"><a href="#sec:CHICKEN_eval_string">CHICKEN_eval_string</a></h3><pre>[C macro] int CHICKEN_eval_string (char *str, C_word *result)</pre><p>Evaluates the Scheme expression passed in the string <tt>str</tt>, writing the result value to <tt>result</tt>.</p><h3 id="sec:CHICKEN_eval_to_string"><a href="#sec:CHICKEN_eval_to_string">CHICKEN_eval_to_string</a></h3><pre>[C macro] int CHICKEN_eval_to_string (C_word exp, char *result, int size)</pre><p>Evaluates the Scheme expression passed in <tt>exp</tt>, writing a textual representation of the result into <tt>result</tt>. <tt>size</tt> should specify the maximal size of the result string.</p><h3 id="sec:CHICKEN_eval_string_to_string"><a href="#sec:CHICKEN_eval_string_to_string">CHICKEN_eval_string_to_string</a></h3><pre>[C macro] int CHICKEN_eval_string_to_string (char *str, char *result, int size)</pre><p>Evaluates the Scheme expression passed in the string <tt>str</tt>, writing a textual representation of the result into <tt>result</tt>. <tt>size</tt> should specify the maximal size of the result string.</p><h3 id="sec:CHICKEN_apply"><a href="#sec:CHICKEN_apply">CHICKEN_apply</a></h3><pre>[C macro] int CHICKEN_apply (C_word func, C_word args, C_word *result)</pre><p>Applies the procedure passed in <tt>func</tt> to the list of arguments <tt>args</tt>, writing the result value to <tt>result</tt>.</p><h3 id="sec:CHICKEN_apply_to_string"><a href="#sec:CHICKEN_apply_to_string">CHICKEN_apply_to_string</a></h3><pre>[C macro] int CHICKEN_apply_to_string (C_word func, C_word args, char *result, int size)</pre><p>Applies the procedure passed in <tt>func</tt> to the list of arguments <tt>args</tt>, writing a textual representation of the result into <tt>result</tt>.</p><h3 id="sec:CHICKEN_read"><a href="#sec:CHICKEN_read">CHICKEN_read</a></h3><pre>[C macro] int CHICKEN_read (char *str, C_word *result)</pre><p>Reads a Scheme object from the string <tt>str</tt>, writing the result value to <tt>result</tt>.</p><h3 id="sec:CHICKEN_load"><a href="#sec:CHICKEN_load">CHICKEN_load</a></h3><pre>[C macro] int CHICKEN_load (char *filename)</pre><p>Loads the Scheme file <tt>filename</tt> (either in source form or compiled).</p><h3 id="sec:CHICKEN_get_error_message"><a href="#sec:CHICKEN_get_error_message">CHICKEN_get_error_message</a></h3><pre>[C macro] void CHICKEN_get_error_message (char *result, int size)</pre><p>Returns a textual description of the most recent error that occurred in executing embedded Scheme code.</p><h3 id="sec:CHICKEN_yield"><a href="#sec:CHICKEN_yield">CHICKEN_yield</a></h3><pre>[C macro] int CHICKEN_yield (int *status)</pre><p>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 <i>idle</i> handler in a GUI application with background Scheme threads.</p><p>An example:</p><pre>% cat x.scm
;;; x.scm
(import (chicken platform) (chicken foreign))

(define (bar x) (gc) (* x x))

(define-external (baz (int i)) double
  (sqrt i))
(return-to-host)
</pre><pre>% cat y.c
/* y.c */

#include &lt;chicken.h&gt;
#include &lt;assert.h&gt;

extern double baz(int);

int main() {
  char buffer[ 256 ];
  int status;
  C_word val = C_SCHEME_UNDEFINED;
  C_word *data[ 1 ];

  data[ 0 ] = &amp;val;

  CHICKEN_run(C_toplevel);

  status = CHICKEN_read(&quot;(bar 99)&quot;, &amp;val);
  assert(status);

  C_gc_protect(data, 1);

  printf(&quot;data: %08x\n&quot;, val);

  status = CHICKEN_eval_string_to_string(&quot;(bar)&quot;, buffer, 255);
  assert(!status);

  CHICKEN_get_error_message(buffer, 255);
  printf(&quot;ouch: %s\n&quot;, buffer);

  status = CHICKEN_eval_string_to_string(&quot;(bar 23)&quot;, buffer, 255);
  assert(status);

  printf(&quot;-&gt; %s\n&quot;, buffer);
  printf(&quot;data: %08x\n&quot;, val);

  status = CHICKEN_eval_to_string(val, buffer, 255);
  assert(status);
  printf(&quot;-&gt; %s\n&quot;, buffer);

  printf(&quot;-&gt;` %g\n&quot;, baz(22));

  return 0;
}

% csc x.scm y.c -embedded</pre><p>It is also possible to re-enter the computation following the call to <tt>return-to-host</tt> by calling <tt>CHICKEN_continue</tt>:</p><h3 id="sec:CHICKEN_continue"><a href="#sec:CHICKEN_continue">CHICKEN_continue</a></h3><pre>[C function] C_word CHICKEN_continue (C_word k)</pre><p>Re-enters Scheme execution. <tt>k</tt> is the continuation received from the previous invocation of <tt>CHICKEN_run</tt> or <tt>CHICKEN_continue</tt>. When <tt>return-to-host</tt> is called again, this function returns another continuation that can be used to restart again.</p><p>If you invoke callbacks prior to calling <tt>CHICKEN_continue</tt>, make sure that the continuation is not reclaimed by garbage collection. This can be avoided by using <tt>C_gc_protect</tt> or gc-roots.</p><p>Another example:</p><pre>% cat x.scm
(import (chicken platform) srfi-18) ;; Needs the srfi-18 egg

(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 &lt;chicken.h&gt;

int main()
{
  C_word k = CHICKEN_run(C_toplevel);

  for(;;)
    k = CHICKEN_continue(k);

  return 0;
}

% csc x.scm y.c -embedded</pre><p>It is advisable not to mix repeated uses of <tt>CHICKEN_continue</tt>/<tt>return-to-host</tt> (as in the example above) with callbacks. Once <tt>return-to-host</tt> is invoked, the runtime system and any Scheme code executed prior to the invocation is initialized and can be conveniently used via callbacks.</p><p>A simpler interface For handling GC-safe references to Scheme data are the so called <i>gc-roots</i>:</p><h3 id="sec:CHICKEN_new_gc_root"><a href="#sec:CHICKEN_new_gc_root">CHICKEN_new_gc_root</a></h3><pre>[C function] void* CHICKEN_new_gc_root ()</pre><p>Returns a pointer to a <i>GC root</i>, 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.</p><h3 id="sec:CHICKEN_new_finalizable_gc_root"><a href="#sec:CHICKEN_new_finalizable_gc_root">CHICKEN_new_finalizable_gc_root</a></h3><pre>[C function] void* CHICKEN_new_finalizable_gc_root ()</pre><p>Similar to <tt>CHICKEN_new_gc_root</tt>, 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.</p><h3 id="sec:CHICKEN_delete_gc_root"><a href="#sec:CHICKEN_delete_gc_root">CHICKEN_delete_gc_root</a></h3><pre>[C function] void CHICKEN_delete_gc_root (void *root)</pre><p>Deletes the gc root.</p><h3 id="sec:CHICKEN_gc_root_ref"><a href="#sec:CHICKEN_gc_root_ref">CHICKEN_gc_root_ref</a></h3><pre>[C macro] C_word CHICKEN_gc_root_ref (void *root)</pre><p>Returns the value stored in the gc root.</p><h3 id="sec:CHICKEN_gc_root_set"><a href="#sec:CHICKEN_gc_root_set">CHICKEN_gc_root_set</a></h3><pre>[C macro] void CHICKEN_gc_root_set (void *root, C_word value)</pre><p>Sets the content of the GC root to a new value.</p><p>Sometimes it is handy to access global variables from C code:</p><h3 id="sec:CHICKEN_global_lookup"><a href="#sec:CHICKEN_global_lookup">CHICKEN_global_lookup</a></h3><pre>[C function] void* CHICKEN_global_lookup (char *name)</pre><p>Returns a GC root that holds the global variable with the name <tt>name</tt>. If no such variable exists, <tt>NULL</tt> is returned.</p><h3 id="sec:CHICKEN_global_ref"><a href="#sec:CHICKEN_global_ref">CHICKEN_global_ref</a></h3><pre>[C function] C_word CHICKEN_global_ref (void *global)</pre><p>Returns the value of the global variable referenced by the GC root <tt>global</tt>.</p><h3 id="sec:CHICKEN_global_set"><a href="#sec:CHICKEN_global_set">CHICKEN_global_set</a></h3><pre>[C function] void CHICKEN_global_set (void *global, C_word value)</pre><p>Sets the value of the global variable referenced by the GC root <tt>global</tt> to <tt>value</tt>.</p><hr /><p>Previous: <a href="Foreign%20type%20specifiers.html">Foreign type specifiers</a></p><p>Next: <a href="C%20interface.html">C interface</a></p></div></div></body>