chickadee » chicken » foreign » define-external

(define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...)syntax
(define-external NAME TYPE [INIT])syntax

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))

You can use location to get a pointer to the defined C function, which can be passed to a C function that takes a callback function pointer argument, for example.

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 ()
  "C_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 a 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 object-evict).

Results of type scheme-object returned by define-external are always allocated in the secondary heap, that is, not in the stack.