(index ("define-external" 0) ("define-external" 0))
(def (sig (syntax "(define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...)" (id define-external)) (syntax "(define-external NAME TYPE [INIT])" (id define-external))) (p "The first form defines an externally callable Scheme procedure. " (tt "NAME") " should be a symbol, which, when converted to a string, represents a legal C identifier. " (tt "ARGUMENTTYPE1 ...") " and " (tt "RETURNTYPE") " are foreign type specifiers for the argument variables " (tt "VAR1 ...") " and the result, respectively.  " (tt "QUALIFIERS") " is an optional qualifier for the foreign procedure definition, like " (tt "__stdcall") ".") (highlight scheme "(define-external (foo (c-string x)) int (string-length x))") (p "The second form of " (tt "define-external") " can be used to define variables that are accessible from foreign code. It declares a global variable named by the symbol " (tt "NAME") " that has the type " (tt "TYPE") ". " (tt "INIT") " can be an arbitrary expression that is used to initialize the variable. " (tt "NAME") " is accessible from Scheme just like any other foreign variable defined by " (tt "define-foreign-variable") ".") (highlight scheme "(define-external foo int 42)\n((foreign-lambda* int ()\n  \"C_return(foo);\"))           ==> 42") (p (b "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 " (tt "object-evict") ").") (p "Results of type " (tt "scheme-object") " returned by " (tt "define-external") " are always allocated in the secondary heap, that is, not in the stack."))
