## 6.4 Callbacks

To enable an external C function to call back to Scheme, the form `foreign-callback-lambda` (or `foreign-callback-lambda*`) has to be used. This generates special code to save and restore important state information during execution of C code. There are two ways of calling Scheme procedures from C: the first is to invoke the runtime function `C_callback` with the closure to be called and the number of arguments. The second is to define an externally visible wrapper function around a Scheme procedure with the `define-external` or `foreign-callback-wrapper` forms. *****

Note: the names of all functions, variables and macros exported by the Chicken runtime system start with ```C_`''. It is advisable to use a different naming scheme for your own code to avoid name clashes.

[syntax] (define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...)
[syntax] (define-external NAME TYPE [INIT])
  The first form defines an externally callable Scheme procedure. `NAME` should be a symbol, which, when converted to a string, represents a legal C identifier. `ARGUMENTTYPE1 ...` and `RETURNTYPE` are foreign type specifiers for the argument variables `VAR1 ...` and the result, respectively. `QUALIFIERS` is an optional qualifier for the foreign procedure definition, like `__stdcall`.

      (define-external (foo (c-string x)) int (string-length x))

  is equivalent to

      (define foo
        (foreign-callback-wrapper int "foo"
          (c-string) (lambda (x) (string-length x))))

  The second form of `define-external` can be used to define variables that are accessible from foreign code. It declares a global variable named by the symbol `NAME` that has the type `TYPE`. `INIT` can be an arbitrary expression that is used to initialize the variable. `NAME` is accessible from Scheme just like any other foreign variable defined by `define-foreign-variable`.

      (define-external foo int 42)
      ((foreign-lambda* int ()
        "return(foo);"))           ==> 42

  Note: don't be tempted to assign strings or bytevectors to external variables. Garbage collection moves those objects around, so it is very bad idea to assign pointers to heap-data. If you have to do so, then copy the data object into statically allocated memory (for example by using `evict`).

[syntax] (foreign-callback-wrapper RETURNTYPE NAME [QUALIFIERS] (ARGUMENTTYPE1 ...) EXP)
  Defines an externally callable wrapper around the procedure `EXP`. `EXP` must be a lambda expression of the form `(lambda `...`)`. The wrapper will have the name `NAME` and will have a signature as specified in the return- and argument-types given in `RETURNTYPE` and `ARGUMENTTYPE1 ...`. `QUALIFIERS` is a qualifier string for the function definition (see `define-external`).

[C function] C_word C_callback(C_word closure, int argc)
  This function can be used to invoke the Scheme procedure `closure`. `argc` should contain the number of arguments that are passed to the procedure on the temporary stack. Values are put onto the temporary stack with the `C_save` macro.