## 6.1 Accessing external objects

[syntax] (define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])
  Defines an alias for `TYPE`. `TYPE` may be a type-specifier or a string naming a C type. The namespace of foreign type specifiers is separate from the normal Scheme namespace. The optional arguments `ARGCONVERT` and `RETCONVERT` should evaluate to procedures that map argument- and result-values to a value that can be transformed to `TYPE`:

      (declare (uses extras))

      (define-foreign-type char-vector
        nonnull-c-string
        (compose list->string vector->list)
        (compose list->vector string->list) )

      (define strlen
        (foreign-lambda int "strlen" char-vector) )

      (strlen '#(#\a#\b#\c))                      ==> 3

      (define memset
        (foreign-lambda char-vector "memset" char-vector char int) )

      (memset '#(#\_ #\_ #\_) #\X3)                ==> #(#\X#\X#\X)

  Foreign type-definitions are only visible in the compilation-unit in which they are defined, so use `include` to use the same definitions in multiple files.

[syntax] (define-foreign-variable NAME TYPE [STRING])
  Defines a foreign variable of name `NAME`. `STRING` should be the real name of a foreign variable or parameterless macro. If `STRING` is not given, then the variable name `NAME` will be converted to a string and used instead. All references and assignments (via `set!`) are modified to correctly convert values between Scheme and C representation. This foreign variable can only be accessed in the current compilation unit, but the name can be lexically shadowed. Note that `STRING` can name an arbitrary C expression. If no assignments are performed, then `STRING` doesn't even have to specify an lvalue.

      #>
      enum { abc=3, def, ghi };
      <#

      (define-macro (define-foreign-enum . items)
        `(begin
           ,@(map (match-lambda
                    [(name realname) `(define-foreign-variable ,name int ,realname)]
                    [name `(define-foreign-variable ,name int)] )
           items) ) )

      (define-foreign-enum abc def ghi)

      ghi                               ==> 5

[syntax] (foreign-callback-lambda RETURNTYPE NAME ARGTYPE)
  This is similar to `foreign-lambda`, but also allows the called function to call Scheme functions. See 6.4.

[syntax] (foreign-callback-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
  This is similar to `foreign-lambda*`, but also allows the called function to call Scheme functions. See 6.4.

[syntax] (foreign-lambda RETURNTYPE NAME ARGTYPE ...)
  Represents a binding to an external routine. This form can be used in the position of an ordinary `lambda` expression. `NAME` specifies the name of the external procedure and should be a string or a symbol.

[syntax] (foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)
  Similar to `foreign-lambda`, but instead of generating code to call an external function, the body of the C procedure is directly given in `STRING ...`:

      (define my-strlen
        (foreign-lambda* int ((c-string str))
          "int n = 0;
           while(*(str++)) ++n;
           return(n);") )

      (my-strlen "one two three")             ==> 13

  For obscure technical reasons any use of the `return` statement should enclose the result value in parentheses. For the same reasons `return` without an argument is not allowed.