chickadee » jiffi » define-binding

(define-binding ...)syntax

Defines a Scheme procedure which calls a C function or C macro. This is syntactic sugar for define and foreign-lambda.

Usage:

(define-binding (SCHEME-NAME FUNC_NAME)      ; or just SCHEME-NAME
  safe:   SAFE                               ; optional
  return: RETURN-TYPE                        ; optional
  args:   ((ARG-TYPE ARG_NAME) ...))         ; optional

SCHEME-NAME is the procedure name to define in Scheme. FUNC_NAME is a non-quoted symbol or string containing the name of the C function or C macro. If SCHEME-NAME and FUNC_NAME are the same, you can write SCHEME-NAME instead of (SCHEME-NAME FUNC_NAME).

If SAFE is #t, the binding will use foreign-safe-lambda. You should do this if you want the C function to be able to call back into Scheme. If SAFE is #f or the safe: clause is omitted, the binding will use foreign-lambda.

RETURN-TYPE is a foreign type specifier describing the return value of the function.

Each ARG-TYPE is a foreign type specifier describing that argument's type.

Each ARG_NAME is a non-quoted symbol describing the argument, usually the argument name in C. This is not actually used in the macro, but it makes it easier for you to see that the binding has the correct number and order of arguments, so mistakes are less likely.

If the return: clause is omitted, the return type is void. If the args: clause is omitted, the procedure accepts no arguments.

Examples:

;; C function and macro definitions
(foreign-declare "
FOO_Event* FOO_CreateKeyEvent(FOO_KeyCode code, FOO_KeyMod mods) {
  FOO_Event* ev = malloc(sizeof(FOO_Event));
  ev->type = FOO_EVENT_TYPE_KEY;
  ev->key.code = code;
  ev->key.mods = mods;
  return ev;
}

#define FOO_ADD1(x) ((x) + 1)
")

;; Binding to a C function, with scheme-style name, and custom foreign
;; types (see examples in the "Armor wrapper" and "Armor unwrapper"
;; sections) to automatically convert return value and args.
(define-binding (create-key-event FOO_CreateKeyEvent)
  return: FOO_KeyEvent*
  args: ((FOO_KeyCode code)
         (FOO_KeyMod mods)))

;; Binding to a C macro
(define-binding FOO_ADD1
  return: int
  args: ((int x)))

(define ev (create-key-event 'a '(lctrl)))
(key-event-code ev) ; ⇒ 'a
(key-event-mods ev) ; ⇒ '(lctrl)

(FOO_ADD1 4)        ; ⇒ 5